wanshenmean
5 小时以前 314076388f664f8ce1a1d19c4c9717fe54634e05
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
@@ -1,4 +1,6 @@
using SqlSugar;
using Newtonsoft.Json;
using SqlSugar;
using WIDESEA_Common.Constants;
using WIDESEA_Common.StockEnum;
using WIDESEA_Core;
using WIDESEA_DTO.MES;
@@ -35,6 +37,16 @@
        public IStockInfo_HtyService StockInfo_HtyService { get; }
        /// <summary>
        /// 仓库服务
        /// </summary>
        public IWarehouseService _warehouseService { get; }
        /// <summary>
        /// SqlSugar客户端(用于临时表操作)
        /// </summary>
        public ISqlSugarClient SqlSugarClient { get; }
        /// <summary>
        /// Mes接口服务
        /// </summary>
        public IMesService _mesService { get; }
@@ -51,13 +63,17 @@
            IStockInfoService stockInfoService,
            IStockInfoDetail_HtyService stockInfoDetail_HtyService,
            IStockInfo_HtyService stockInfo_HtyService,
            IMesService mesService)
            IMesService mesService,
            IWarehouseService warehouseService,
            ISqlSugarClient sqlSugarClient)
        {
            StockInfoDetailService = stockInfoDetailService;
            StockInfoService = stockInfoService;
            StockInfoDetail_HtyService = stockInfoDetail_HtyService;
            StockInfo_HtyService = stockInfo_HtyService;
            _mesService = mesService;
            _warehouseService = warehouseService;
            SqlSugarClient = sqlSugarClient;
        }
        /// <summary>
@@ -116,32 +132,18 @@
                var now = DateTime.Now;
                var details = stock.Details.Select(item => new Dt_StockInfoDetail
                {
                    MaterielCode = "电芯",
                    MaterielName = "电芯",
                    MaterielCode = StockConstants.MATERIAL_CODE,
                    MaterielName = StockConstants.MATERIAL_NAME,
                    StockQuantity = item.Quantity,
                    Unit = "PCS",
                    Creater = "system",
                    OrderNo = "111",
                    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 bindRequest = new BindContainerRequest
                {
                    ContainerCode = stock?.TargetPalletNo,
                    EquipmentCode = "STK-GROUP-001",
                    ResourceCode = "STK-GROUP-001",
                    LocalTime = now,
                    OperationType = 0, // 0代表组盘
                    ContainerSfcList = details.Select(d => new ContainerSfcItem
                    {
                        Sfc = d.SerialNumber,
                        Location = d.InboundOrderRowNo.ToString(),
                    }).ToList()
                };
                return await ExecuteWithinTransactionAsync(async () =>
                {
@@ -154,23 +156,23 @@
                        return result ? content.OK("组盘成功") : content.Error("组盘失败");
                    }
                    int WarehouseId = stock.Roadway switch
                    {
                        "注液组盘机械手" => (await _warehouseService.Db.Queryable<Dt_Warehouse>().FirstAsync(w => w.WarehouseCode == "GWSC1")).WarehouseId,
                        "换盘机械手" => (await _warehouseService.Db.Queryable<Dt_Warehouse>().FirstAsync(w => w.WarehouseCode == "HCSC1")).WarehouseId
                    };
                    var entity = new Dt_StockInfo
                    {
                        PalletCode = stock.TargetPalletNo,
                        //WarehouseId = stock.WarehouseId > 0 ? stock.WarehouseId : 1,
                        WarehouseId = 1,
                        WarehouseId = WarehouseId,
                        StockStatus = StockStatusEmun.组盘暂存.GetHashCode(),
                        Creater = "system",
                        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("组盘成功");
                });
            }
@@ -209,7 +211,7 @@
                            PalletCode = stock.TargetPalletNo,
                            WarehouseId = sourceStock.WarehouseId,
                            StockStatus = StockStatusEmun.组盘暂存.GetHashCode(),
                            Creater = "system",
                            Creater = StockConstants.SYSTEM_USER,
                        };
                        var newId = StockInfoService.Repository.AddData(newStock);
@@ -235,6 +237,7 @@
                    detailEntities.ForEach(d => d.StockId = targetStock.Id);
                    var result = await StockInfoDetailService.Repository.UpdateDataAsync(detailEntities);
                    if (!result) return content.Error("换盘失败");
                    return content.OK("换盘成功");
                });
            }
@@ -254,6 +257,30 @@
            {
                if (stock == null || string.IsNullOrWhiteSpace(stock.SourcePalletNo))
                    return content.Error("源托盘号不能为空");
                // 幂等写入:检查临时表是否已有该托盘记录,无则写入
                var existingTemp = SqlSugarClient.Queryable<Dt_SplitTemp>()
                    .Where(t => t.PalletCode == stock.SourcePalletNo)
                    .First();
                if (existingTemp == null)
                {
                    // 查询该托盘当前所有电芯,存入临时表
                    var sourceStockForTemp = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.SourcePalletNo);
                    if (sourceStockForTemp != null)
                    {
                        var allDetails = StockInfoDetailService.Repository.QueryData(d => d.StockId == sourceStockForTemp.Id);
                        if (allDetails != null && allDetails.Any())
                        {
                            var sfcListJson = JsonConvert.SerializeObject(allDetails.Select(d => d.SerialNumber).ToList());
                            await SqlSugarClient.Insertable(new Dt_SplitTemp
                            {
                                PalletCode = stock.SourcePalletNo,
                                SfcList = sfcListJson,
                                CreateTime = DateTime.Now
                            }).ExecuteCommandAsync();
                        }
                    }
                }
                return await ExecuteWithinTransactionAsync(async () =>
                {
@@ -279,8 +306,6 @@
                    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("拆盘成功");
                });
            }
@@ -362,5 +387,177 @@
                OutboundDate = s.OutboundDate
            }).ToList();
        }
        /// <summary>
        /// 批量拆盘确认 - 一次性调用MES解绑整个托盘
        /// </summary>
        /// <param name="palletCode">源托盘号</param>
        /// <param name="deviceName">设备名称(用于动态MES凭证查询)</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> SplitPalletConfirmAsync(string palletCode, string deviceName)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (string.IsNullOrWhiteSpace(palletCode))
                    return content.Error("托盘号不能为空");
                // 1. 从临时表读取电芯列表
                var tempRecord = SqlSugarClient.Queryable<Dt_SplitTemp>()
                    .Where(t => t.PalletCode == palletCode)
                    .First();
                if (tempRecord == null)
                    return content.Error("未找到拆盘临时记录,请先执行拆盘操作");
                var sfcList = JsonConvert.DeserializeObject<List<string>>(tempRecord.SfcList);
                if (sfcList == null || !sfcList.Any())
                    return content.Error("临时表中电芯列表为空");
                // 2. 获取MES设备配置(动态凭证)
                string equipmentCode = StockConstants.MES_EQUIPMENT_CODE;
                string resourceCode = StockConstants.MES_RESOURCE_CODE;
                string token = null;
                if (!string.IsNullOrWhiteSpace(deviceName))
                {
                    var mesConfig = ResolveMesConfig(deviceName, palletCode);
                    if (mesConfig != null)
                    {
                        equipmentCode = mesConfig.EquipmentCode;
                        resourceCode = mesConfig.ResourceCode;
                        token = mesConfig.Token;
                    }
                }
                // 3. 调用MES解绑
                var unbindRequest = new UnBindContainerRequest
                {
                    EquipmentCode = equipmentCode,
                    ResourceCode = resourceCode,
                    LocalTime = DateTime.Now,
                    ContainCode = palletCode,
                    SfcList = sfcList
                };
                var unbindResult = string.IsNullOrWhiteSpace(token)
                    ? _mesService.UnBindContainer(unbindRequest)
                    : _mesService.UnBindContainer(unbindRequest, token);
                if (unbindResult == null || unbindResult.Data == null || !unbindResult.Data.IsSuccess)
                {
                    return content.Error($"MES解绑失败: {unbindResult?.Data?.Msg ?? unbindResult?.ErrorMessage ?? "未知错误"}");
                }
                // 4. 删除临时表记录
                await SqlSugarClient.Deleteable<Dt_SplitTemp>().Where(t => t.PalletCode == palletCode).ExecuteCommandAsync();
                return content.OK("批量拆盘确认成功");
            }
            catch (Exception ex)
            {
                return content.Error($"批量拆盘确认失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 批量组盘确认 - 一次性调用MES绑定整个托盘
        /// </summary>
        /// <param name="palletCode">目标托盘号</param>
        /// <param name="deviceName">设备名称(用于动态MES凭证查询)</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode, string deviceName)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (string.IsNullOrWhiteSpace(palletCode))
                    return content.Error("托盘号不能为空");
                // 1. 查询该托盘下的所有电芯明细
                var stockInfo = StockInfoService.Repository.QueryFirst(s => s.PalletCode == palletCode);
                if (stockInfo == null)
                    return content.Error("托盘不存在");
                var details = StockInfoDetailService.Repository.QueryData(d => d.StockId == stockInfo.Id);
                if (details == null || !details.Any())
                    return content.Error("托盘下无电芯数据");
                // 2. 获取MES设备配置(动态凭证)
                string equipmentCode = StockConstants.MES_EQUIPMENT_CODE;
                string resourceCode = StockConstants.MES_RESOURCE_CODE;
                string token = null;
                if (!string.IsNullOrWhiteSpace(deviceName))
                {
                    var mesConfig = ResolveMesConfig(deviceName, palletCode);
                    if (mesConfig != null)
                    {
                        equipmentCode = mesConfig.EquipmentCode;
                        resourceCode = mesConfig.ResourceCode;
                        token = mesConfig.Token;
                    }
                }
                // 3. 调用MES绑定
                var bindRequest = new BindContainerRequest
                {
                    ContainerCode = palletCode,
                    EquipmentCode = equipmentCode,
                    ResourceCode = resourceCode,
                    LocalTime = DateTime.Now,
                    OperationType = StockConstants.MES_BIND_OPERATION_TYPE,
                    ContainerSfcList = details.Select(d => new ContainerSfcItem
                    {
                        Sfc = d.SerialNumber,
                        Location = d.InboundOrderRowNo.ToString()
                    }).ToList()
                };
                var bindResult = string.IsNullOrWhiteSpace(token)
                    ? _mesService.BindContainer(bindRequest)
                    : _mesService.BindContainer(bindRequest, token);
                if (bindResult == null || bindResult.Data == null || !bindResult.Data.IsSuccess)
                {
                    return content.Error($"MES绑定失败: {bindResult?.Data?.Msg ?? bindResult?.ErrorMessage ?? "未知错误"}");
                }
                return content.OK("批量组盘确认成功");
            }
            catch (Exception ex)
            {
                return content.Error($"批量组盘确认失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 根据设备名称和托盘号解析MES设备配置
        /// </summary>
        /// <param name="deviceName">设备名称</param>
        /// <param name="palletCode">托盘号(用于查询仓库编码)</param>
        /// <returns>MES设备配置,不存在时返回null</returns>
        private Dt_MESDeviceConfig ResolveMesConfig(string deviceName, string palletCode)
        {
            // 换盘机械手需要区分仓库
            if (deviceName.Contains("换盘"))
            {
                // 查询托盘对应的仓库编码
                var stockInfo = StockInfoService.Repository.QueryFirst(s => s.PalletCode == palletCode);
                if (stockInfo != null && stockInfo.WarehouseId > 0)
                {
                    var warehouse = _warehouseService.Repository.QureyDataById(stockInfo.WarehouseId);
                    if (warehouse != null && !string.IsNullOrWhiteSpace(warehouse.WarehouseCode))
                    {
                        // 先按设备名+仓库编码查询
                        var config = SqlSugarClient.Queryable<Dt_MESDeviceConfig>()
                            .Where(c => c.DeviceName == deviceName && c.WarehouseCode == warehouse.WarehouseCode)
                            .First();
                        if (config != null)
                            return config;
                    }
                }
            }
            // 按设备名称查询(适用于组盘机械手或换盘机械手未找到仓库匹配的情况)
            return SqlSugarClient.Queryable<Dt_MESDeviceConfig>()
                .Where(c => c.DeviceName == deviceName)
                .First();
        }
    }
}