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 "1":
return InsertBarcode(barcodeEntity);
case "2":
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 "1":
groupResultList.Add(InsertBarcodeBatch(entityGroup));
break;
case "2":
groupResultList.Add(DeleteBarcodeBatch(entityGroup.Select(e => e.Id).ToArray()));
break;
default:
throw new ArgumentOutOfRangeException(nameof(type),type,"批量操作中存在非法Type:仅支持 1(新增)、2(删除)");
}
}
// 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 == "1" ? Guid.NewGuid() : (string.IsNullOrEmpty(dto.SmallBarcode) ? Guid.Empty : Guid.NewGuid());
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 == "1" ? 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)
{
// 检查条码是否已存在
if (IsBarcodeExists(entity))
{
throw new InvalidOperationException($"条码已存在,无法重复插入:SmallBarcode={entity.SmallBarcode}, OuterBarcode={entity.OuterBarcode}");
}
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 duplicateBarcodes = new List();
foreach (var entity in entityList)
{
if (IsBarcodeExists(entity))
{
duplicateBarcodes.Add($"SmallBarcode={entity.SmallBarcode}, OuterBarcode={entity.OuterBarcode}");
}
}
if (duplicateBarcodes.Any())
{
throw new InvalidOperationException($"发现重复条码,无法批量插入:{string.Join("; ", duplicateBarcodes)}");
}
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");
}
///
/// 检查条码是否已存在
///
/// 条码实体
/// true=已存在,false=不存在
private bool IsBarcodeExists(BarcodeInformation entity)
{
// 根据SmallBarcode或OuterBarcode检查是否存在重复条码
return Db.Queryable()
.Any(x => (!string.IsNullOrEmpty(entity.SmallBarcode) && x.SmallBarcode == entity.SmallBarcode) ||
(!string.IsNullOrEmpty(entity.OuterBarcode) && x.OuterBarcode == entity.OuterBarcode));
}
#endregion
}