using MES.Service.DB; using MES.Service.Dto.webApi; using MES.Service.Modes; using System.Linq; using MES.Service.util; namespace MES.Service.service.BasicData; /// /// 送货单条码业务管理器(对应TBL_BARCODE_INFORMATION表操作) /// public class DeliveryBarcodeManager : Repository { /// /// 单个送货单条码信息保存(支持新增/删除,按Type区分操作类型) /// /// 送货单条码DTO(含操作类型Type) /// 操作是否成功 public bool Save(DeliveryBarcodeInfo barcodeDto) { if (barcodeDto == null) throw new ArgumentNullException(nameof(barcodeDto), "条码DTO不能为空"); // DTO转实体(映射字段关系) var barcodeEntity = ConvertDtoToEntity(barcodeDto); try { // 按Type区分操作类型(0=新增,1=删除) switch (barcodeDto.Type) { case "0": return InsertBarcode(barcodeEntity); case "1": return DeleteBarcode(barcodeEntity.Id); default: throw new ArgumentOutOfRangeException( nameof(barcodeDto.Type), barcodeDto.Type, "条码操作类型错误:仅支持 0(新增)、1(删除)"); } } catch (Exception ex) { throw new ApplicationException($"单个条码操作失败(送货单号:{barcodeDto.DeliveryNo}):{ex.Message}", ex); } } /// /// 批量送货单条码信息保存(按Type分组处理,统一异常捕获) /// /// 送货单条码DTO列表 /// 批量操作是否全部成功 public bool SaveList(List barcodeDtoList) { if (barcodeDtoList == null || !barcodeDtoList.Any()) { throw new ArgumentException("批量操作的条码列表不能为空"); } try { // 1. 创建强类型的实体与类型组合列表(解决dynamic转换问题) var entityTypePairs = new List(); foreach (var dto in barcodeDtoList) { entityTypePairs.Add(new EntityTypePair { Entity = ConvertDtoToEntity(dto), Type = dto.Type }); } // 2. 按操作类型Type分组(使用强类型避免类型推断问题) var typeGroupDict = entityTypePairs .GroupBy(pair => pair.Type) .ToDictionary( group => group.Key, group => group.Select(pair => pair.Entity).ToList() ); // 3. 存储各组操作结果 var groupResultList = new List(); foreach (var (type, entityGroup) in typeGroupDict) { switch (type) { case "0": groupResultList.Add(InsertBarcodeBatch(entityGroup)); break; case "1": groupResultList.Add(DeleteBarcodeBatch(entityGroup.Select(e => e.Id).ToArray())); break; default: throw new ArgumentOutOfRangeException( nameof(type), type, "批量操作中存在非法Type:仅支持 0(新增)、1(删除)"); } } // 4. 所有分组操作均成功才算批量成功 if (groupResultList.All(result => result)) { return true; } throw new NotImplementedException("批量条码操作部分失败,具体请查看日志"); } catch (Exception ex) { throw new ApplicationException($"批量条码操作失败(总条数:{barcodeDtoList.Count}):{ex.Message}", ex); } } /// /// 根据送货单号删除条码数据 /// /// 送货单号(不能为空/空字符串) /// 是否删除成功(true=至少删除1条,false=未找到对应数据) public bool DeleteByDeliveryNo(string deliveryNo) { // 1. 校验参数:送货单号不能为空 if (string.IsNullOrWhiteSpace(deliveryNo)) throw new ArgumentException("送货单号 DeliveryNo 不能为空或空格", nameof(deliveryNo)); try { // 2. 执行删除:根据 DeliveryNo 匹配表中数据(对应实体的 DeliveryNo 字段) int deletedCount = Db.Deleteable() .Where(barcode => barcode.DeliveryNo == deliveryNo) // 表字段与送货单号匹配 .ExecuteCommand(); // 返回受影响的行数 // 3. 判断结果:至少删除1条则视为成功,否则抛出“未找到数据”异常 if (deletedCount > 0) return true; throw new KeyNotFoundException($"未找到送货单号为「{deliveryNo}」的条码数据,删除操作未执行"); } catch (Exception ex) { // 4. 包装业务异常,补充上下文信息 throw new ApplicationException($"根据送货单号删除条码数据失败(DeliveryNo:{deliveryNo}):{ex.Message}", ex); } } /// /// 批量按送货单号删除条码数据(接收数组项列表) /// /// 包含DeliveryNo的对象列表 /// 批量删除结果 public BatchDeleteResult DeleteListByDeliveryNo(List deliveryNoItems) { // 1. 参数校验与处理(从控制器移过来的逻辑) if (deliveryNoItems == null || !deliveryNoItems.Any()) throw new ArgumentException("送货单号列表不能为空", nameof(deliveryNoItems)); // 提取并验证送货单号列表 var deliveryNoList = deliveryNoItems .Select(item => item.DeliveryNo) // 从对象中提取DeliveryNo字段 .Where(no => !string.IsNullOrWhiteSpace(no)) // 过滤空值/空格 .Distinct() // 去重,避免重复删除 .ToList(); // 判断是否有有效单号 if (!deliveryNoList.Any()) throw new ArgumentException("请求中没有有效的送货单号(均为空或空格)"); try { // 2. 查询数据库中存在的送货单号 var existingNos = Db.Queryable() .Where(barcode => deliveryNoList.Contains(barcode.DeliveryNo)) .Select(barcode => barcode.DeliveryNo) .Distinct() .ToList(); // 3. 执行批量删除 int totalDeleted = Db.Deleteable() .Where(barcode => deliveryNoList.Contains(barcode.DeliveryNo)) .ExecuteCommand(); // 4. 返回结果 return new BatchDeleteResult { TotalRequested = deliveryNoList.Count, TotalDeleted = totalDeleted, DeletedNos = existingNos, NotFoundNos = deliveryNoList.Except(existingNos).ToList() }; } catch (Exception ex) { throw new ApplicationException( $"批量删除失败(共{deliveryNoList.Count}个单号):{ex.Message}", ex); } } /// /// 按送货单号+行内码联合删除条码数据 /// /// 送货单号 /// 送货单行内码 /// 是否删除成功(true=至少删除1条,false=未找到对应数据) public bool DeleteByDeliveryItem(string deliveryNo, string lineNo) { // 1. 双参数校验:避免空值/空字符串 if (string.IsNullOrWhiteSpace(deliveryNo)) throw new ArgumentException("送货单号 DeliveryNo 不能为空或空格", nameof(deliveryNo)); if (string.IsNullOrWhiteSpace(lineNo)) throw new ArgumentException("送货单行内码 LineNo 不能为空或空格", nameof(lineNo)); try { // 2. 联合条件删除:匹配 DeliveryNo(送货单号)和 DnLines(行内码,实体字段对应表的 dnLines 列) int deletedCount = Db.Deleteable() .Where(barcode => barcode.DeliveryNo == deliveryNo // 匹配送货单号 && barcode.DnLines == lineNo // 匹配行内码(实体 DnLines 对应表 dnLines 字段) ) .ExecuteCommand(); // 返回受影响的行数 // 3. 结果判断:有数据被删除则成功,否则抛“未找到数据”异常 if (deletedCount > 0) return true; throw new KeyNotFoundException( $"未找到送货单号「{deliveryNo}」且行内码「{lineNo}」对应的条码数据,删除操作未执行"); } catch (Exception ex) { // 4. 包装异常:补充联合条件上下文,便于定位问题 throw new ApplicationException( $"按送货单号+行内码删除条码数据失败(DeliveryNo:{deliveryNo},LineNo:{lineNo}):{ex.Message}", ex); } } /// /// 批量按送货单号+行内码删除条码数据 /// /// 包含DeliveryNo和LineNo的对象列表 /// 批量删除结果 public BatchDeleteResult DeleteListByDeliveryItem(List deliveryItems) { // 1. 参数校验与处理 if (deliveryItems == null || !deliveryItems.Any()) throw new ArgumentException("送货单行列表不能为空", nameof(deliveryItems)); // 提取并验证送货单号+行内码组合 var validItems = deliveryItems .Where(item => !string.IsNullOrWhiteSpace(item.DeliveryNo) && !string.IsNullOrWhiteSpace(item.LineNo) ) .Select(item => new { DeliveryNo = item.DeliveryNo, LineNo = item.LineNo }) .Distinct() // 去重相同的组合 .ToList(); if (!validItems.Any()) throw new ArgumentException("请求中没有有效的效的送货单行数据(均为空或空格)"); try { // 2. 执行批量删除(按DeliveryNo+LineNo组合条件) int totalDeleted = 0; var deletedItems = new List(); var notFoundItems = new List(); // 遍历每个组合执行删除(或使用批量条件删除) foreach (var item in validItems) { // 检查当前组合是否存在 var exists = Db.Queryable() .Any(b => b.DeliveryNo == item.DeliveryNo && b.DnLines == item.LineNo); if (exists) { // 执行删除 var deleted = Db.Deleteable() .Where(b => b.DeliveryNo == item.DeliveryNo && b.DnLines == item.LineNo) .ExecuteCommand(); totalDeleted += deleted; deletedItems.Add($"{item.DeliveryNo}_{item.LineNo}"); } else { notFoundItems.Add($"{item.DeliveryNo}_{item.LineNo}"); } } // 3. 返回结果 return new BatchDeleteResult { TotalRequested = validItems.Count, TotalDeleted = totalDeleted, DeletedNos = deletedItems, // 存储格式:"DeliveryNo_LineNo" NotFoundNos = notFoundItems // 存储格式:"DeliveryNo_LineNo" }; } catch (Exception ex) { throw new ApplicationException( $"批量删除送货单行失败(共{validItems.Count}条):{ex.Message}", ex); } } #region 私有辅助方法和内部类 /// /// 内部辅助类:用于关联实体和操作类型(解决dynamic类型转换问题) /// private class EntityTypePair { public BarcodeInformation Entity { get; set; } public string Type { get; set; } } /// /// DTO转实体:映射DeliveryBarcodeInfo到BarcodeInformation字段 /// private BarcodeInformation ConvertDtoToEntity(DeliveryBarcodeInfo dto) { var entityId = dto.Type == "0" ? Guid.NewGuid() : (string.IsNullOrEmpty(dto.SmallBarcode) ? Guid.Empty : Guid.Parse(dto.SmallBarcode)); return new BarcodeInformation { Id = entityId, ProductCode = dto.ProductCode, SmallBarcode = dto.SmallBarcode, OuterBarcode = dto.OuterBarcode, IncludeQty = dto.IncludeQty.HasValue ? Convert.ToDecimal(dto.IncludeQty) : 0, DeliveryNo = dto.DeliveryNo, DnLines = dto.LineNo, PackLevel = dto.BarcodeType, CreateTime = dto.Type == "0" ? DateTime.Now : (DateTime?)null, UpdateTime = DateTime.Now, // 扩展字段赋默认值 BigBarcode = null, SmallPackageLength = null, SmallPackageWidth = null, SmallPackageHeight = null, BigPackageLength = null, BigPackageWidth = null, BigPackageHeight = null, OuterPackageLength = null, OuterPackageWidth = null, OuterPackageHeight = null, SmallPackageSn = null, BigPackageSn = null, OutPackageSn = null, DynamicData = null, PoErpNo = null, PoLineNo = null, InnerVendorCode = null, Customize1 = null, SynchronousDate = null, Customize2 = null, Customize3 = null }; } /// /// 单个条码新增 /// private bool InsertBarcode(BarcodeInformation entity) { var isInsertSuccess = base.Insert(entity); return isInsertSuccess ? true : throw new NotImplementedException("条码新增失败:数据库插入操作未执行成功"); } /// /// 单个条码删除(按主键Id) /// private bool DeleteBarcode(Guid id) { if (id == Guid.Empty) throw new ArgumentException("删除操作的条码Id不能为空"); var deleteRowCount = Db.Deleteable() .Where(entity => entity.Id == id) .ExecuteCommand(); return deleteRowCount > 0 ? true : throw new NotImplementedException($"条码删除失败:未找到Id为「{id}」的条码记录"); } /// /// 批量条码新增 /// private bool InsertBarcodeBatch(List entityList) { var isBatchInsertSuccess = base.InsertRange(entityList); return isBatchInsertSuccess ? true : throw new NotImplementedException($"批量条码新增失败:共{entityList.Count}条记录"); } /// /// 批量条码删除(按主键Id数组) /// private bool DeleteBarcodeBatch(Guid[] ids) { if (ids == null || ids.Length == 0) throw new ArgumentException("批量删除的条码Id数组不能为空"); var deleteRowCount = Db.Deleteable() .Where(entity => ids.Contains(entity.Id)) .ExecuteCommand(); return deleteRowCount > 0 ? true : throw new NotImplementedException($"批量条码删除失败:共{ids.Length}个Id"); } #endregion }