wanshenmean
5 天以前 5171d3f59b89389bf75293afd210cfa6de4ccff7
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
@@ -1,31 +1,116 @@
using WIDESEA_Common.StockEnum;
using SqlSugar;
using WIDESEA_Common.Constants;
using WIDESEA_Common.StockEnum;
using WIDESEA_Core;
using WIDESEA_DTO.MES;
using WIDESEA_DTO.Stock;
using WIDESEA_IBasicService;
using WIDESEA_IStockService;
using WIDESEA_Model.Models;
namespace WIDESEA_StockService
{
    /// <summary>
    /// 库存服务
    /// 库存服务聚合实现类
    /// </summary>
    public class StockSerivce : IStockService
    public class StockService : IStockService
    {
        /// <summary>
        /// 库存明细服务
        /// </summary>
        public IStockInfoDetailService StockInfoDetailService { get; }
        /// <summary>
        /// 库存信息服务
        /// </summary>
        public IStockInfoService StockInfoService { get; }
        /// <summary>
        /// 库存明细历史服务
        /// </summary>
        public IStockInfoDetail_HtyService StockInfoDetail_HtyService { get; }
        /// <summary>
        /// 库存历史服务
        /// </summary>
        public IStockInfo_HtyService StockInfo_HtyService { get; }
        public StockSerivce(
        /// <summary>
        /// 仓库服务
        /// </summary>
        public IWarehouseService _warehouseService { get; }
        /// <summary>
        /// Mes接口服务
        /// </summary>
        public IMesService _mesService { get; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="stockInfoDetailService">库存明细服务</param>
        /// <param name="stockInfoService">库存信息服务</param>
        /// <param name="stockInfoDetail_HtyService">库存明细历史服务</param>
        /// <param name="stockInfo_HtyService">库存历史服务</param>
        public StockService(
            IStockInfoDetailService stockInfoDetailService,
            IStockInfoService stockInfoService,
            IStockInfoDetail_HtyService stockInfoDetail_HtyService,
            IStockInfo_HtyService stockInfo_HtyService)
            IStockInfo_HtyService stockInfo_HtyService,
            IMesService mesService,
            IWarehouseService warehouseService)
        {
            StockInfoDetailService = stockInfoDetailService;
            StockInfoService = stockInfoService;
            StockInfoDetail_HtyService = stockInfoDetail_HtyService;
            StockInfo_HtyService = stockInfo_HtyService;
            _mesService = mesService;
            _warehouseService = warehouseService;
        }
        /// <summary>
        /// 在事务中执行操作
        /// </summary>
        private async Task<WebResponseContent> ExecuteWithinTransactionAsync(Func<Task<WebResponseContent>> operation)
        {
            var db = StockInfoService.Repository.Db as SqlSugarClient;
            if (db == null)
            {
                return WebResponseContent.Instance.Error("Database context does not support transactions");
            }
            var ownsTransaction = db.Ado.Transaction == null;
            try
            {
                if (ownsTransaction)
                {
                    db.BeginTran();
                }
                var result = await operation();
                if (result?.Status == true)
                {
                    if (ownsTransaction)
                    {
                        db.CommitTran();
                    }
                    return result;
                }
                if (ownsTransaction)
                {
                    db.RollbackTran();
                }
                return result ?? WebResponseContent.Instance.Error("Transaction failed");
            }
            catch
            {
                if (ownsTransaction)
                {
                    db.RollbackTran();
                }
                throw;
            }
        }
        /// <summary>
@@ -34,44 +119,72 @@
        public async Task<WebResponseContent> GroupPalletAsync(StockDTO stock)
        {
            WebResponseContent content = new WebResponseContent();
            var now = DateTime.Now;
            var details = stock.Details.Select(item => new Dt_StockInfoDetail
            try
            {
                MaterielCode = "电芯",
                MaterielName = "电芯",
                StockQuantity = item.Quantity,
                Unit = "PCS",
                Creater = "system",
                OrderNo = "111",
                ProductionDate = now.ToString(),
                EffectiveDate = now.AddYears(1).ToString(),
                SerialNumber = item.CellBarcode,
                InboundOrderRowNo = item.Channel,
                Status = StockStatusEmun.组盘暂存.GetHashCode(),
            }).ToList();
                var now = DateTime.Now;
                var details = stock.Details.Select(item => new Dt_StockInfoDetail
                {
                    MaterielCode = StockConstants.MATERIAL_CODE,
                    MaterielName = StockConstants.MATERIAL_NAME,
                    StockQuantity = item.Quantity,
                    Unit = StockConstants.UNIT,
                    Creater = StockConstants.SYSTEM_USER,
                    OrderNo = StockConstants.DEFAULT_ORDER_NO,
                    ProductionDate = now.ToString(),
                    EffectiveDate = now.AddYears(1).ToString(),
                    SerialNumber = item.CellBarcode,
                    InboundOrderRowNo = item.Channel,
                    Status = StockStatusEmun.组盘暂存.GetHashCode(),
                }).ToList();
            var existingStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.TargetPalletNo);
            var result = false;
            if (existingStock != null)
            {
                details.ForEach(d => d.StockId = existingStock.Id);
                result = await StockInfoDetailService.Repository.AddDataAsync(details) > 0;
                if (result) return content.OK("组盘成功");
                return content.Error("组盘失败");
                var bindRequest = new BindContainerRequest
                {
                    ContainerCode = stock?.TargetPalletNo,
                    EquipmentCode = StockConstants.MES_EQUIPMENT_CODE,
                    ResourceCode = StockConstants.MES_RESOURCE_CODE,
                    LocalTime = now,
                    OperationType = StockConstants.MES_BIND_OPERATION_TYPE,
                    ContainerSfcList = details.Select(d => new ContainerSfcItem
                    {
                        Sfc = d.SerialNumber,
                        Location = d.InboundOrderRowNo.ToString(),
                    }).ToList()
                };
                return await ExecuteWithinTransactionAsync(async () =>
                {
                    var existingStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.TargetPalletNo);
                    var result = false;
                    if (existingStock != null)
                    {
                        details.ForEach(d => d.StockId = existingStock.Id);
                        result = await StockInfoDetailService.Repository.AddDataAsync(details) > 0;
                        return result ? content.OK("组盘成功") : content.Error("组盘失败");
                    }
                    var entity = new Dt_StockInfo
                    {
                        PalletCode = stock.TargetPalletNo,
                        WarehouseId = stock.Roadway == "注液组盘机械手" ? (await _warehouseService.Db.Queryable<Dt_Warehouse>().FirstAsync(w => w.WarehouseCode == "GW1")).WarehouseId : 0,
                        StockStatus = StockStatusEmun.组盘暂存.GetHashCode(),
                        Creater = StockConstants.SYSTEM_USER,
                        Details = details
                    };
                    result = StockInfoService.Repository.AddData(entity, x => x.Details);
                    if (!result) return content.Error("组盘失败");
                    //var mesResult = _mesService.BindContainer(bindRequest);
                    //if (mesResult == null || mesResult.Data == null || !mesResult.Data.IsSuccess)
                    //{
                    //    return content.Error($"组盘成功,但MES绑定失败: {mesResult?.Data?.Msg ?? mesResult?.ErrorMessage ?? "未知错误"}");
                    //}
                    return content.OK("组盘成功");
                });
            }
            var entity = new Dt_StockInfo
            catch (Exception ex)
            {
                PalletCode = stock.TargetPalletNo,
                WarehouseId = 1,
                StockStatus = 1,
                Creater = "system",
                Details = details
            };
            result = StockInfoService.Repository.AddData(entity, x => x.Details);
            if (result) return content.OK("组盘成功");
            return content.Error("组盘失败");
                return content.Error($"组盘失败: {ex.Message}");
            }
        }
        /// <summary>
@@ -80,52 +193,98 @@
        public async Task<WebResponseContent> ChangePalletAsync(StockDTO stock)
        {
            WebResponseContent content = new WebResponseContent();
            if (stock == null ||
                string.IsNullOrWhiteSpace(stock.TargetPalletNo) ||
                string.IsNullOrWhiteSpace(stock.SourcePalletNo) ||
                string.Equals(stock.SourcePalletNo, stock.TargetPalletNo, StringComparison.OrdinalIgnoreCase))
            try
            {
                return content.Error("源托盘号与目标托盘号相同");
            }
            var sourceStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.SourcePalletNo);
            if (sourceStock == null) return content.Error("源托盘不存在");
            var targetStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.TargetPalletNo);
            if (targetStock == null)
            {
                var newStock = new Dt_StockInfo
                if (stock == null ||
                    string.IsNullOrWhiteSpace(stock.TargetPalletNo) ||
                    string.IsNullOrWhiteSpace(stock.SourcePalletNo) ||
                    string.Equals(stock.SourcePalletNo, stock.TargetPalletNo, StringComparison.OrdinalIgnoreCase))
                {
                    PalletCode = stock.TargetPalletNo,
                    WarehouseId = sourceStock.WarehouseId,
                    StockStatus = StockStatusEmun.组盘暂存.GetHashCode(),
                    Creater = "system",
                };
                    return content.Error("源托盘号与目标托盘号相同");
                }
                var newId = StockInfoService.Repository.AddData(newStock);
                if (newId <= 0) return content.Error("换盘失败");
                return await ExecuteWithinTransactionAsync(async () =>
                {
                    var sourceStock = await StockInfoService.Repository.QueryDataNavFirstAsync(s => s.PalletCode == stock.SourcePalletNo);
                    if (sourceStock == null) return content.Error("源托盘不存在");
                targetStock = newStock;
                targetStock.Id = newId;
                    var targetStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.TargetPalletNo);
                    if (targetStock == null)
                    {
                        var newStock = new Dt_StockInfo
                        {
                            PalletCode = stock.TargetPalletNo,
                            WarehouseId = sourceStock.WarehouseId,
                            StockStatus = StockStatusEmun.组盘暂存.GetHashCode(),
                            Creater = StockConstants.SYSTEM_USER,
                        };
                        var newId = StockInfoService.Repository.AddData(newStock);
                        if (newId <= 0) return content.Error("换盘失败");
                        targetStock = newStock;
                        targetStock.Id = newId;
                    }
                    var serialNumbers = stock.Details.Select(d => d.Channel).Distinct().ToList();
                    if (!serialNumbers.Any()) return content.Error("未找到有效的序列号");
                    var detailEntities = StockInfoDetailService.Repository.QueryData(
                        d => d.StockId == sourceStock.Id && serialNumbers.Contains(d.InboundOrderRowNo));
                    if (!detailEntities.Any()) return content.Error("未找到有效的库存明细");
                    if (await StockInfoDetail_HtyService.Repository.AddDataAsync(CreateDetailHistory(detailEntities, "换盘")) <= 0)
                        return content.Error("换盘历史记录保存失败");
                    if (await StockInfo_HtyService.Repository.AddDataAsync(CreateStockHistory(new[] { sourceStock, targetStock }, "换盘")) <= 0)
                        return content.Error("换盘历史记录保存失败");
                    // 调用MES解绑源托盘电芯
                    var unbindRequest = new UnBindContainerRequest
                    {
                        EquipmentCode = StockConstants.MES_EQUIPMENT_CODE,
                        ResourceCode = StockConstants.MES_RESOURCE_CODE,
                        LocalTime = DateTime.Now,
                        ContainCode = stock.SourcePalletNo,
                        SfcList = detailEntities.Select(d => d.SerialNumber).ToList()
                    };
                    var unbindResult = _mesService.UnBindContainer(unbindRequest);
                    if (unbindResult == null || unbindResult.Data == null || !unbindResult.Data.IsSuccess)
                    {
                        return content.Error($"换盘成功,但MES解绑失败: {unbindResult?.Data?.Msg ?? unbindResult?.ErrorMessage ?? "未知错误"}");
                    }
                    detailEntities.ForEach(d => d.StockId = targetStock.Id);
                    var result = await StockInfoDetailService.Repository.UpdateDataAsync(detailEntities);
                    if (!result) return content.Error("换盘失败");
                    // 调用MES绑定目标托盘电芯
                    var bindRequest = new BindContainerRequest
                    {
                        ContainerCode = stock.TargetPalletNo,
                        EquipmentCode = StockConstants.MES_EQUIPMENT_CODE,
                        ResourceCode = StockConstants.MES_RESOURCE_CODE,
                        LocalTime = DateTime.Now,
                        OperationType = StockConstants.MES_BIND_OPERATION_TYPE,
                        ContainerSfcList = detailEntities.Select(d => new ContainerSfcItem
                        {
                            Sfc = d.SerialNumber,
                            Location = d.InboundOrderRowNo.ToString()
                        }).ToList()
                    };
                    var bindResult = _mesService.BindContainer(bindRequest);
                    if (bindResult == null || bindResult.Data == null || !bindResult.Data.IsSuccess)
                    {
                        return content.Error($"换盘成功,但MES绑定失败: {bindResult?.Data?.Msg ?? bindResult?.ErrorMessage ?? "未知错误"}");
                    }
                    return content.OK("换盘成功");
                });
            }
            var serialNumbers = stock.Details.Select(d => d.CellBarcode).Distinct().ToList();
            if (!serialNumbers.Any()) return content.Error("未找到有效的序列号");
            var detailEntities = StockInfoDetailService.Repository.QueryData(
                d => d.StockId == sourceStock.Id && serialNumbers.Contains(d.SerialNumber));
            if (!detailEntities.Any()) return content.Error("未找到有效的库存明细");
            if (await StockInfoDetail_HtyService.Repository.AddDataAsync(CreateDetailHistory(detailEntities, "换盘")) <= 0)
                return content.Error("换盘历史记录保存失败");
            if (await StockInfo_HtyService.Repository.AddDataAsync(CreateStockHistory(new[] { sourceStock, targetStock }, "换盘")) <= 0)
                return content.Error("换盘历史记录保存失败");
            detailEntities.ForEach(d => d.StockId = targetStock.Id);
            var result = await StockInfoDetailService.Repository.UpdateDataAsync(detailEntities);
            if (!result) return content.Error("换盘失败");
            return content.OK("换盘成功");
            catch (Exception ex)
            {
                return content.Error($"换盘失败: {ex.Message}");
            }
        }
        /// <summary>
@@ -134,34 +293,59 @@
        public async Task<WebResponseContent> SplitPalletAsync(StockDTO stock)
        {
            WebResponseContent content = new WebResponseContent();
            if (stock == null || string.IsNullOrWhiteSpace(stock.SourcePalletNo))
                return content.Error("源托盘号不能为空");
            var sourceStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.SourcePalletNo);
            if (sourceStock == null) return content.Error("源托盘不存在");
            var serialNumbers = stock.Details.Select(d => d.CellBarcode).Distinct().ToList();
            if (!serialNumbers.Any())
            try
            {
                serialNumbers = sourceStock.Details
                                            .Where(x => stock.Details.Any(d => d.Channel == x.InboundOrderRowNo))
                                            .Select(x => x.SerialNumber)
                                            .ToList();
                if (stock == null || string.IsNullOrWhiteSpace(stock.SourcePalletNo))
                    return content.Error("源托盘号不能为空");
                return await ExecuteWithinTransactionAsync(async () =>
                {
                    var sourceStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.SourcePalletNo);
                    if (sourceStock == null) return content.Error("源托盘不存在");
                    var serialNumbers = stock.Details.Select(d => d.CellBarcode).Distinct().ToList();
                    if (!serialNumbers.Any())
                    {
                        serialNumbers = sourceStock.Details
                                                    .Where(x => stock.Details.Any(d => d.Channel == x.InboundOrderRowNo))
                                                    .Select(x => x.SerialNumber)
                                                    .ToList();
                    }
                    var detailEntities = StockInfoDetailService.Repository.QueryData(
                        d => d.StockId == sourceStock.Id && serialNumbers.Contains(d.SerialNumber));
                    if (!detailEntities.Any()) return content.Error("未找到有效的库存明细");
                    if (await StockInfoDetail_HtyService.Repository.AddDataAsync(CreateDetailHistory(detailEntities, "拆盘")) <= 0)
                        return content.Error("拆盘历史记录保存失败");
                    if (await StockInfo_HtyService.Repository.AddDataAsync(CreateStockHistory(new[] { sourceStock }, "拆盘")) <= 0)
                        return content.Error("拆盘历史记录保存失败");
                    // 调用MES解绑电芯
                    var unbindRequest = new UnBindContainerRequest
                    {
                        EquipmentCode = StockConstants.MES_EQUIPMENT_CODE,
                        ResourceCode = StockConstants.MES_RESOURCE_CODE,
                        LocalTime = DateTime.Now,
                        ContainCode = stock.SourcePalletNo,
                        SfcList = detailEntities.Select(d => d.SerialNumber).ToList()
                    };
                    var unbindResult = _mesService.UnBindContainer(unbindRequest);
                    if (unbindResult == null || unbindResult.Data == null || !unbindResult.Data.IsSuccess)
                    {
                        return content.Error($"拆盘成功,但MES解绑失败: {unbindResult?.Data?.Msg ?? unbindResult?.ErrorMessage ?? "未知错误"}");
                    }
                    var result = await StockInfoDetailService.Repository.DeleteDataAsync(detailEntities);
                    if (!result) return content.Error("拆盘失败");
                    return content.OK("拆盘成功");
                });
            }
            var detailEntities = StockInfoDetailService.Repository.QueryData(
                d => d.StockId == sourceStock.Id && serialNumbers.Contains(d.SerialNumber));
            if (!detailEntities.Any()) return content.Error("未找到有效的库存明细");
            if (await StockInfoDetail_HtyService.Repository.AddDataAsync(CreateDetailHistory(detailEntities, "拆盘")) <= 0)
                return content.Error("拆盘历史记录保存失败");
            if (await StockInfo_HtyService.Repository.AddDataAsync(CreateStockHistory(new[] { sourceStock }, "拆盘")) <= 0)
                return content.Error("拆盘历史记录保存失败");
            var result = await StockInfoDetailService.Repository.DeleteDataAsync(detailEntities);
            if (!result) return content.Error("拆盘失败");
            return content.OK("拆盘成功");
            catch (Exception ex)
            {
                return content.Error($"拆盘失败: {ex.Message}");
            }
        }
        /// <summary>
@@ -231,7 +415,9 @@
                Creater = s.Creater,
                CreateDate = s.CreateDate,
                Modifier = s.Modifier,
                ModifyDate = s.ModifyDate
                ModifyDate = s.ModifyDate,
                LocationId = s.LocationId,
                OutboundDate = s.OutboundDate
            }).ToList();
        }
    }