From 2009f6a879446b23a0ba1356468c95c1e327fe1a Mon Sep 17 00:00:00 2001 From: gwbvipvip Date: Mon, 8 Jul 2024 17:35:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99=E5=95=86=E5=93=81=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=EF=BC=8C=E5=95=86=E5=93=81=E5=8F=8A=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E9=AA=8C=E9=87=8D20240708?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- commit-395b6f0 | 553 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 553 insertions(+) create mode 100644 commit-395b6f0 diff --git a/commit-395b6f0 b/commit-395b6f0 new file mode 100644 index 0000000..11a6cf1 --- /dev/null +++ b/commit-395b6f0 @@ -0,0 +1,553 @@ +From 395b6f040824087ef4616402b301ef7ae19f825e Mon Sep 17 00:00:00 2001 +From: gwbvipvip +Date: Mon, 8 Jul 2024 17:27:56 +0800 +Subject: 重写商品导入,商品及分类验重 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + +diff --git a/BPA.SAAS.Manage.Application/DataBase/Dtos/Goods/GoodsDto.cs b/BPA.SAAS.Manage.Application/DataBase/Dtos/Goods/GoodsDto.cs +index 99d9933..d896ecd 100644 +--- a/BPA.SAAS.Manage.Application/DataBase/Dtos/Goods/GoodsDto.cs ++++ b/BPA.SAAS.Manage.Application/DataBase/Dtos/Goods/GoodsDto.cs +@@ -1,4 +1,5 @@ + using BPA.SAAS.Manage.Comm.Enum; ++using Npoi.Mapper.Attributes; + using System; + using System.Collections.Generic; + using System.Linq; +@@ -24,4 +25,22 @@ namespace BPA.SAAS.Manage.Application.DataBase.Dtos.Goods + public string GoodsTypeId { get; set; } + public string Status { get; set; } + } ++ ++ public class GoodsImportDto ++ { ++ [Column("商品名称")] ++ public string Name { get;set; } ++ [Column("商品分类")] ++ public string Type { get; set; } ++ [Column("商品单位")] ++ public string Uint { get; set; } ++ [Column("商品价格")] ++ public decimal Price { get; set; } ++ [Column("是否称重")] ++ public string IsWeigh { get; set; } ++ [Column("备注")] ++ public string Descritption { get; set; } ++ [Column("图片")] ++ public object ImgUrl { get; set; } ++ } + } +diff --git a/BPA.SAAS.Manage.Application/DataBase/Dtos/Goods/GoodsTechnologyImportDto.cs b/BPA.SAAS.Manage.Application/DataBase/Dtos/Goods/GoodsTechnologyImportDto.cs +index b9fec40..08978b6 100644 +--- a/BPA.SAAS.Manage.Application/DataBase/Dtos/Goods/GoodsTechnologyImportDto.cs ++++ b/BPA.SAAS.Manage.Application/DataBase/Dtos/Goods/GoodsTechnologyImportDto.cs +@@ -11,7 +11,7 @@ namespace BPA.SAAS.Manage.Application.DataBase.Dtos.Goods + /// + /// 文件 + /// +- public IFormFile file { get; set; } ++ public IFormFile File { get; set; } + } + + public class GoodsTechnologyExportDto +@@ -29,4 +29,12 @@ namespace BPA.SAAS.Manage.Application.DataBase.Dtos.Goods + /// + public string FileName { get; set; } + } ++ ++ public class GoodsInfoImportDto ++ { ++ /// ++ /// 文件 ++ /// ++ public IFormFile File { get; set; } ++ } + } +diff --git a/BPA.SAAS.Manage.Application/DataBase/GoodsServices.cs b/BPA.SAAS.Manage.Application/DataBase/GoodsServices.cs +index c88368f..ce5fc0c 100644 +--- a/BPA.SAAS.Manage.Application/DataBase/GoodsServices.cs ++++ b/BPA.SAAS.Manage.Application/DataBase/GoodsServices.cs +@@ -205,13 +205,36 @@ namespace BPA.SAAS.Manage.Application.DataBase + } + + /// +- /// 商品工艺导出 ++ /// 商品工艺模版导出 + /// ++ /// + /// + [HttpPost("/api/goods/goodsTechnologyExport"), NonUnify] + public async Task GoodsTechnologyExport(GoodsTechnologyExportDto exportDto) + { + return await _goodsService.GoodsTechnologyExport(exportDto); + } ++ ++ /// ++ /// 商品导入 ++ /// ++ /// ++ /// ++ [HttpPost("/api/goods/goodsImport"), NonUnify] ++ public async Task GoodsImport([FromForm] GoodsInfoImportDto importDto) ++ { ++ return await _goodsService.GoodsImport(importDto); ++ } ++ ++ /// ++ /// 商品工艺导出 ++ /// ++ /// ++ /// ++ [HttpPost("/api/goods/goodsSimpleExport"), NonUnify] ++ public async Task GoodsSimpleExport(string goodName) ++ { ++ return await _goodsService.GoodsSimpleExport(goodName); ++ } + } + } +diff --git a/BPA.SAAS.Manage.Application/DataBase/Interface/IGoodsService.cs b/BPA.SAAS.Manage.Application/DataBase/Interface/IGoodsService.cs +index 29f725a..c628ddb 100644 +--- a/BPA.SAAS.Manage.Application/DataBase/Interface/IGoodsService.cs ++++ b/BPA.SAAS.Manage.Application/DataBase/Interface/IGoodsService.cs +@@ -111,9 +111,23 @@ namespace BPA.SAAS.Manage.Application.DataBase.Interface + Task GoodsTechnologyImport([FromForm] GoodsTechnologyImportDto importDto); + + /// +- /// 商品工艺导出 ++ /// 商品工艺模版导出 + /// + /// + Task GoodsTechnologyExport(GoodsTechnologyExportDto exportDto); ++ ++ /// ++ /// 商品导入 ++ /// ++ /// ++ /// ++ Task GoodsImport([FromForm] GoodsInfoImportDto importDto); ++ ++ /// ++ /// 商品工艺导出 ++ /// ++ /// ++ /// ++ Task GoodsSimpleExport(string goodName); + } + } +diff --git a/BPA.SAAS.Manage.Application/DataBase/Services/GoodsService.cs b/BPA.SAAS.Manage.Application/DataBase/Services/GoodsService.cs +index 63f13a1..08f787d 100644 +--- a/BPA.SAAS.Manage.Application/DataBase/Services/GoodsService.cs ++++ b/BPA.SAAS.Manage.Application/DataBase/Services/GoodsService.cs +@@ -1,5 +1,4 @@ +-using BPA.Franchisee.Application.FranchiseeCenter.GoodsServices; +-using BPA.SAAS.Manage.Application.DataBase.Dtos; ++using BPA.SAAS.Manage.Application.DataBase.Dtos; + using BPA.SAAS.Manage.Application.DataBase.Dtos.Batching; + using BPA.SAAS.Manage.Application.DataBase.Dtos.Bom; + using BPA.SAAS.Manage.Application.DataBase.Dtos.Goods; +@@ -34,7 +33,6 @@ using System.Linq; + using System.Reflection; + using System.Text; + using System.Text.RegularExpressions; +-using System.Threading.Tasks; + + namespace BPA.SAAS.Manage.Application.DataBase.Services + { +@@ -44,14 +42,12 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + IGoodsAttributeService _goodsAttributeService; + ISystemConfigService _SystemConfigService; + IAliyunOssService _aliyunOssService; +- IWebHostEnvironment _hostingEnvironment; + public GoodsService(ISqlSugarClient db, IGoodsAttributeService goodsAttributeService, ISystemConfigService SystemConfigService, IAliyunOssService aliyunOssService, IWebHostEnvironment webHostEnvironment) + { + _db=db; + _goodsAttributeService=goodsAttributeService; + _SystemConfigService = SystemConfigService; + _aliyunOssService = aliyunOssService; +- _hostingEnvironment = webHostEnvironment; + } + /// + /// 分页查询 +@@ -383,7 +379,7 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + var productCode = _db.Queryable().Where(x =>x.Name == dto.Name).ToList(); + if (productCode.Count() > 0) + { +- throw Oops.Oh("商品单位已存在"); ++ throw Oops.Oh($"{dto.Name}已存在,添加失败!"); + } + try + { +@@ -392,9 +388,9 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + var res = await _db.Insertable(bPA_Product).CallEntityMethod(m => m.Create()).ExecuteCommandAsync(); + return res > 0; + } +- catch (Exception ex) ++ catch (Exception e) + { +- throw Oops.Oh("添加失败"); ++ throw Oops.Oh(e.Message); + } + } + /// +@@ -1257,15 +1253,170 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + return true; + } + ++ /// ++ /// 商品导入 ++ /// ++ /// ++ /// ++ public async Task GoodsImport(GoodsInfoImportDto importDto) ++ { ++ var file = importDto.File; ++ var aliyunHost = "https://bpa.oss-cn-chengdu.aliyuncs.com/"; ++ var userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value; ++ if (string.IsNullOrEmpty(userId)) ++ { ++ userId = ""; ++ } ++ var goodsInfo = await _db.Queryable().ToListAsync(); ++ var goodsType = await _db.Queryable().ToListAsync(); ++ var goodsUint = await _db.Queryable().ToListAsync(); ++ try ++ { ++ _db.Ado.BeginTran(); ++ var source = file.OpenReadStream(); ++ var mapper = new Mapper(source); ++ var excelDto = new ReadExcel(); ++ var dataList = excelDto.ExcelToList(source, mapper); ++ dataList.RemoveAll(t => t.Name == null); ++ UpdateGoodsImportDto(dataList); ++ var imageList = await GetImagesWithExcel(file.OpenReadStream(), Path.GetExtension(file.FileName)); ++ var newUnitList = new List(); ++ var i = 0; ++ foreach (var data in dataList) ++ { ++ if (data.Type == null) ++ throw Oops.Oh($"商品分类不能为空!"); ++ if (data.Name == null) ++ throw Oops.Oh($"商品名称不能为空!"); ++ if (data.Uint == null) ++ throw Oops.Oh($"商品单位不能为空!"); ++ var type = goodsType.FirstOrDefault(t => t.Name == data.Type); ++ if (type == null) ++ throw Oops.Oh($"{data.Name} 不存在分类:{data.Type}!"); ++ var old = goodsInfo.FirstOrDefault(t => t.Name == data.Name && t.GoodsTypeId == type.Id); ++ if (old != null) ++ throw Oops.Oh($"{data.Name} 已存在该商品!"); ++ var uintId = ""; ++ var uintData = goodsUint.FirstOrDefault(t => t.Name == data.Uint); ++ var newUnitData = newUnitList.FirstOrDefault(t => t.Name == data.Uint); ++ if (uintData != null || newUnitData != null) ++ uintId = uintData != null ? uintData.Id : newUnitData.Id; ++ else ++ { ++ uintId = Guid.NewGuid().ToString(); ++ var newUint = new BPA_GoodsUint ++ { ++ Id = uintId, ++ Name = data.Uint, ++ CreateBy = userId ++ }; ++ newUnitList.Add(newUint); ++ await _db.Insertable(newUint).ExecuteCommandAsync(); ++ } ++ var imgUrl = data.ImgUrl != null ? data.ImgUrl.ToString() : ""; ++ if (!imgUrl.Contains("=DISPIMG")) ++ imgUrl = null; ++ else ++ { ++ imgUrl = aliyunHost + imageList[i]; ++ i++; ++ } ++ var newValue = new BPA_GoodsInfo ++ { ++ Id = Guid.NewGuid().ToString(), ++ Name = data.Name, ++ GoodsTypeId = type.Id, ++ Descritption = data.Descritption, ++ ImgUrl = imgUrl, ++ Code = GetNumber2(8), ++ Price = data.Price, ++ CreateBy = userId, ++ GoodsUintId = uintId, ++ IsWeigh = data.IsWeigh == "是", ++ IsAttrubute = true ++ }; ++ await _db.Insertable(newValue).ExecuteCommandAsync(); ++ } ++ _db.Ado.CommitTran(); ++ } ++ catch (Exception e) ++ { ++ _db.Ado.RollbackTran(); ++ throw Oops.Oh($"Excel导入错误," + e.Message); ++ } ++ return true; ++ } ++ ++ public List UpdateGoodsImportDto(List list) ++ { ++ foreach (var item in list) ++ { ++ item.Name = item.Name?.Trim(); ++ item.Type = item.Type?.Trim(); ++ item.Uint = item.Uint?.Trim(); ++ item.IsWeigh = item.IsWeigh?.Trim(); ++ item.Descritption = item.Descritption?.Trim(); ++ } ++ return list; ++ } ++ ++ public async Task> GetImagesWithExcel(Stream stream, string fileType) ++ { ++ try ++ { ++ var result = new List(); ++ IWorkbook workbook; ++ if (fileType == ".xlsx") ++ { ++ workbook = new XSSFWorkbook(stream); ++ var pictures = workbook.GetAllPictures(); ++ foreach (XSSFPictureData pic in pictures) ++ { ++ using (var ms = new MemoryStream(pic.Data)) ++ { ++ var suffix = pic.SuggestFileExtension(); ++ var fileName = Guid.NewGuid().ToString(); ++ IFormFile formFile = new FormFile(ms, 0, ms.Length, "name", $"{fileName}.{suffix}"); ++ result.Add(await _aliyunOssService.UpFileAsync(formFile)); ++ } ++ } ++ } ++ else if (fileType == ".xls") ++ { ++ workbook = new HSSFWorkbook(stream); ++ var pictures = workbook.GetAllPictures(); ++ foreach (HSSFPictureData pic in pictures) ++ { ++ using (var ms = new MemoryStream(pic.Data)) ++ { ++ var suffix = pic.SuggestFileExtension(); ++ var fileName = Guid.NewGuid().ToString(); ++ IFormFile formFile = new FormFile(ms, 0, ms.Length, "name", $"{fileName}.{suffix}"); ++ result.Add(await _aliyunOssService.UpFileAsync(formFile)); ++ } ++ } ++ } ++ else ++ { ++ throw new Exception("传入的不是Excel文件!"); ++ } ++ return result; ++ } ++ catch (Exception ex) ++ { ++ throw new Exception(ex.Message); ++ } ++ } ++ + /// + /// 商品工艺导入 + /// + /// + /// + public async Task GoodsTechnologyImport(GoodsTechnologyImportDto importDto) +- { ++ { + string pattern = @"(?[^,(]+),(?\([^)]+\)),(?[^,]+)"; +- var file = importDto.file; ++ var file = importDto.File; + var userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value; + if (string.IsNullOrEmpty(userId)) + { +@@ -1480,7 +1631,7 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + } + + /// +- /// 商品工艺导出 ++ /// 商品工艺模版导出 + /// + /// + /// +@@ -1576,7 +1727,7 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + sheet.AddMergedRegion(new CellRangeAddress(1, 2, 4, 4)); + #endregion + } +- var tempFolder = Path.Combine(_hostingEnvironment.ContentRootPath, "TechnologyTemplate"); ++ var tempFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TechnologyTemplate"); + if (!Directory.Exists(tempFolder)) + Directory.CreateDirectory(tempFolder); + var time = DateTime.Now.ToString("yyyy年MM月dd日HH时mm分ss秒"); +@@ -1589,6 +1740,70 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + return fileBase64; + } + ++ /// ++ /// 商品工艺导出 ++ /// ++ /// ++ /// ++ public async Task GoodsSimpleExport(string goodName) ++ { ++ var goodsAttributeList = await _db.Queryable().ToListAsync(); ++ var goodsAttributeValueList = await _db.Queryable().Where(t => goodsAttributeList.Select(a => a.Id).Contains(t.GoodsAttributeId)).OrderBy(a => a.Sort).ToListAsync(); ++ var goodsType = await _db.Queryable().ToListAsync(); ++ var goodsInfo = await _db.Queryable().FirstAsync(t => t.Name == goodName); ++ if (goodsInfo == null) ++ throw Oops.Oh("商品不存在!"); ++ var actionList = await _db.Queryable().Where(t => t.GoodsId == goodsInfo.Id).OrderBy(a => a.GoodsAttributeId).OrderBy(a => a.Order).ToListAsync(); ++ IWorkbook workbook = new XSSFWorkbook(); ++ string[] charsToReplace = new string[] { "\\", "/", "?", "*", "[", "]" }; ++ foreach (string c in charsToReplace) ++ { ++ goodName = goodName.Replace(c, " "); ++ } ++ ISheet sheet = workbook.CreateSheet(goodName); ++ IRow headerRow = sheet.CreateRow(0); ++ headerRow.CreateCell(0).SetCellValue("商品名称"); ++ headerRow.CreateCell(1).SetCellValue("属性组合"); ++ headerRow.CreateCell(2).SetCellValue("工序"); ++ headerRow.CreateCell(3).SetCellValue("工序参数"); ++ headerRow.CreateCell(4).SetCellValue("参数值"); ++ var k = 1; ++ for (int i = 0; i < actionList.Count; i++) ++ { ++ var stepName = actionList[i].StepName; ++ var attributeNames = ""; ++ var attributeNameList = new List(); ++ var goodsAttributeIdList = actionList[i].GoodsAttributeId.Split(','); ++ foreach (var goodsAttributeId in goodsAttributeIdList) ++ { ++ attributeNameList.Add(goodsAttributeValueList.FirstOrDefault(t => t.Id == goodsAttributeId)?.AttributeValue); ++ } ++ attributeNames = string.Join("-", attributeNameList); ++ var actionJsonList = JsonConvert.DeserializeObject>(actionList[i].ActionJson); ++ for (int j = 0; j < actionJsonList.Count; j++) ++ { ++ IRow dataRow = sheet.CreateRow(k); ++ dataRow.CreateCell(0).SetCellValue(goodName); ++ dataRow.CreateCell(1).SetCellValue(attributeNames); ++ dataRow.CreateCell(2).SetCellValue(stepName); ++ dataRow.CreateCell(3).SetCellValue(actionJsonList[j].actionName); ++ dataRow.CreateCell(4).SetCellValue(actionJsonList[j].actionValue); ++ k++; ++ } ++ } ++ var tempFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GoodsTechnologyData"); ++ if (!Directory.Exists(tempFolder)) ++ Directory.CreateDirectory(tempFolder); ++ var time = DateTime.Now.ToString("yyyy年MM月dd日HH时mm分ss秒"); ++ var filePath = Path.Combine(tempFolder, $"{goodName}导出-{time}.xlsx"); ++ using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) ++ { ++ workbook.Write(stream); ++ } ++ var fileBase64 = Convert.ToBase64String(File.ReadAllBytes(filePath)); ++ return fileBase64; ++ } ++ + public static List GenerateCombinations(Dictionary> values, bool isId, BPA_GoodsInfo goodInfo, BPA_DeviceInfo deviceInfo) + { + var attributes = values.Keys.ToList(); +@@ -1858,5 +2073,6 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + var str = string.Format("{0}", ram.ToString().Substring(0, Length)); + return str; + } ++ + } + } +diff --git a/BPA.SAAS.Manage.Application/DataBase/Services/GoodsTypeService.cs b/BPA.SAAS.Manage.Application/DataBase/Services/GoodsTypeService.cs +index 44e08c6..42500c8 100644 +--- a/BPA.SAAS.Manage.Application/DataBase/Services/GoodsTypeService.cs ++++ b/BPA.SAAS.Manage.Application/DataBase/Services/GoodsTypeService.cs +@@ -93,6 +93,9 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + { + try + { ++ var old = await _db.Queryable().FirstAsync(t => t.Name == dto.Name); ++ if (old != null) ++ throw Oops.Oh($"已存在{dto.Name},添加失败!"); + var res = 0; + if (string.IsNullOrWhiteSpace(dto.Id)) + { +@@ -132,10 +135,10 @@ namespace BPA.SAAS.Manage.Application.DataBase.Services + return res > 0; + } + } +- catch (Exception) ++ catch (Exception e) + { + _db.Ado.RollbackTran(); +- throw Oops.Oh("添加失败!"); ++ throw Oops.Oh(e.Message); + } + } + public async Task HandleGoodsAttribute(BPA_GoodsType typeEntity, List AttributeList) +diff --git a/BPA.SAAS.Manage.Application/System/AliyunOssServices.cs b/BPA.SAAS.Manage.Application/System/AliyunOssServices.cs +index 5cb3938..613d2dc 100644 +--- a/BPA.SAAS.Manage.Application/System/AliyunOssServices.cs ++++ b/BPA.SAAS.Manage.Application/System/AliyunOssServices.cs +@@ -23,5 +23,11 @@ namespace BPA.SAAS.Manage.Application.System + { + return await _aliyunOssService.GeneratePostPolicyAsync(request); + } ++ ++ [HttpPost("/api/systemconfig/UpFileAsync"), ApiDescriptionSettings(SplitCamelCase = false), AllowAnonymous, NonUnify] ++ public async Task UpFileAsync(IFormFile formFile) ++ { ++ return await _aliyunOssService.UpFileAsync(formFile); ++ } + } + } +diff --git a/BPA.SAAS.Manage.Application/System/Interface/IAliyunOssService.cs b/BPA.SAAS.Manage.Application/System/Interface/IAliyunOssService.cs +index e619ed5..3730776 100644 +--- a/BPA.SAAS.Manage.Application/System/Interface/IAliyunOssService.cs ++++ b/BPA.SAAS.Manage.Application/System/Interface/IAliyunOssService.cs +@@ -11,5 +11,6 @@ namespace BPA.SAAS.Manage.Application.System.Interface + public interface IAliyunOssService + { + Task GeneratePostPolicyAsync(Aliyun0ssGeneratePostPolicyRequest request); ++ Task UpFileAsync(IFormFile formFile); + } + } +diff --git a/BPA.SAAS.Manage.Application/System/Services/AliyunOssService.cs b/BPA.SAAS.Manage.Application/System/Services/AliyunOssService.cs +index 69afe6f..fa3c4c9 100644 +--- a/BPA.SAAS.Manage.Application/System/Services/AliyunOssService.cs ++++ b/BPA.SAAS.Manage.Application/System/Services/AliyunOssService.cs +@@ -1,4 +1,5 @@ +-using BPA.Aliyun.OSS; ++using Aliyun.OSS.Util; ++using BPA.Aliyun.OSS; + using BPA.Aliyun.OSS.Options; + using BPA.SAAS.Manage.Application.System.Dtos; + using BPA.SAAS.Manage.Application.System.Interface; +@@ -27,5 +28,11 @@ namespace BPA.SAAS.Manage.Application.System.Services + var data = await _aliyunOssClient.GeneratePostPolicyAsync(dir); + return data; + } ++ ++ public async Task UpFileAsync(IFormFile formFile) ++ { ++ var data = await _aliyunOssClient.UpFileAsync(formFile); ++ return data; ++ } + } + } +diff --git a/BPA.SAAS.Manage.Web.Entry/appsettings.json b/BPA.SAAS.Manage.Web.Entry/appsettings.json +index fd1d125..6488e7d 100644 +--- a/BPA.SAAS.Manage.Web.Entry/appsettings.json ++++ b/BPA.SAAS.Manage.Web.Entry/appsettings.json +@@ -41,7 +41,7 @@ + "PresignedUriExpirationMinutes": 1440, + "PolicyExpirationMinutes": 1440, + "ProjectName": "hkerp", +- "ServiceName": "test" ++ "ServiceName": "test/goods" + } + } + },