| | |
| | | using System.ComponentModel; |
| | | using System.Reflection; |
| | | using Newtonsoft.Json; |
| | | using SqlSugar; |
| | | using WIDESEA_Common.Constants; |
| | | using WIDESEA_Common.StockEnum; |
| | | using WIDESEA_Common.TaskEnum; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_Core.Helper; |
| | | using WIDESEA_DTO.MES; |
| | | using WIDESEA_DTO.Task; |
| | | using WIDESEA_Model.Models; |
| | | |
| | |
| | | return descAttr?.Description ?? taskStatus.ToString(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ç»ç/æçæä½å¹¶å建å
¥åºä»»å¡ï¼å®æåä¸åWCS |
| | | /// </summary> |
| | | /// <param name="dto">ç»ç/æçæä½åæ°</param> |
| | | /// <returns>æä½ç»æ</returns> |
| | | public async Task<WebResponseContent> PalletOperationAndCreateTaskAsync(PalletOperationTaskDto dto) |
| | | { |
| | | try |
| | | { |
| | | // 1. åæ°æ ¡éª |
| | | if (string.IsNullOrWhiteSpace(dto.PalletCode)) |
| | | return WebResponseContent.Instance.Error("æçå·ä¸è½ä¸ºç©º"); |
| | | |
| | | if (string.IsNullOrWhiteSpace(dto.Action) |
| | | || (dto.Action != "ç»ç" && dto.Action != "æç")) |
| | | return WebResponseContent.Instance.Error("æ§è¡å¨ä½å¿
é¡»æ¯'ç»ç'æ'æç'"); |
| | | |
| | | if (string.IsNullOrWhiteSpace(dto.LineId)) |
| | | return WebResponseContent.Instance.Error("线ä½ç¼å·ä¸è½ä¸ºç©º"); |
| | | |
| | | if (string.IsNullOrWhiteSpace(dto.WarehouseCode)) |
| | | return WebResponseContent.Instance.Error("ä»åºç¼å·ä¸è½ä¸ºç©º"); |
| | | |
| | | if (string.IsNullOrWhiteSpace(dto.RobotName)) |
| | | return WebResponseContent.Instance.Error("æºæ¢°æåç§°ä¸è½ä¸ºç©º"); |
| | | |
| | | // ç»çæ¶çµè¯å表å¿
ä¼ |
| | | if (dto.Action == "ç»ç" && (dto.Cells == null || !dto.Cells.Any())) |
| | | return WebResponseContent.Instance.Error("ç»çæ¶çµè¯å表ä¸è½ä¸ºç©º"); |
| | | |
| | | // 2. æ ¹æ®ä»åºç¼å·æ¥è¯¢ä»åºä¿¡æ¯ï¼è·å WarehouseIdãtargetAddress å roadway |
| | | var warehouse = _sqlSugarClient.Queryable<Dt_Warehouse>() |
| | | .First(w => w.WarehouseCode == dto.WarehouseCode); |
| | | if (warehouse == null) |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°ä»åºç¼å·ä¸º[{dto.WarehouseCode}]çä»åº"); |
| | | |
| | | int warehouseId = warehouse.WarehouseId; |
| | | string targetAddress = warehouse.WarehouseCode; |
| | | string roadway = warehouse.WarehouseCode; |
| | | |
| | | // 3. æ ¹æ®å¨ä½ç±»åæ§è¡ä¸åæµç¨ |
| | | if (dto.Action == "ç»ç") |
| | | return await ExecuteGroupPalletAsync(dto, warehouseId, targetAddress, roadway); |
| | | |
| | | return await ExecuteSplitPalletAsync(dto, warehouseId, targetAddress, roadway); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return WebResponseContent.Instance.Error($"ç»ç/æçæä½å¼å¸¸: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ§è¡ç»çæä½ï¼æ·»å åºå â ç´æ¥è°ç¨MESç»å® â å建å
¥åºä»»å¡ â ä¸åWCS |
| | | /// </summary> |
| | | private async Task<WebResponseContent> ExecuteGroupPalletAsync( |
| | | PalletOperationTaskDto dto, int warehouseId, string targetAddress, string roadway) |
| | | { |
| | | return await _unitOfWorkManage.BeginTranAsync(async () => |
| | | { |
| | | // 1. å建åºå主记å½ï¼ä¸ç»å®è´§ä½ï¼ |
| | | var stockInfo = new Dt_StockInfo |
| | | { |
| | | PalletCode = dto.PalletCode, |
| | | PalletType = 0, |
| | | WarehouseId = warehouseId, |
| | | LocationId = 0, |
| | | StockStatus = 0, |
| | | MesUploadStatus = 0 |
| | | }; |
| | | var stockId = await _stockInfoService.Repository.AddDataAsync(stockInfo); |
| | | if (stockId <= 0) |
| | | return WebResponseContent.Instance.Error("å建åºåè®°å½å¤±è´¥"); |
| | | |
| | | // 2. æ¹éå建åºåæç» |
| | | var details = dto.Cells.Select((cell, i) => new Dt_StockInfoDetail |
| | | { |
| | | StockId = (int)stockId, |
| | | MaterielCode = cell.SfcCode, |
| | | MaterielName = "", |
| | | OrderNo = "", |
| | | ProductionDate = DateTime.Now.ToString("yyyy-MM-dd"), |
| | | EffectiveDate = "", |
| | | SerialNumber = cell.SfcCode, |
| | | StockQuantity = 1, |
| | | OutboundQuantity = 0, |
| | | Status = 0, |
| | | InboundOrderRowNo = Convert.ToInt32(cell.Channel), |
| | | Remark = cell.Channel |
| | | }).ToList(); |
| | | if (await _sqlSugarClient.Insertable(details).ExecuteCommandAsync() <= 0) |
| | | return WebResponseContent.Instance.Error("å建åºåæç»å¤±è´¥"); |
| | | |
| | | // 3. è°ç¨MESç»å® |
| | | var (equipmentCode, resourceCode, token) = ResolveMesConfig(dto.RobotName); |
| | | var bindRequest = new BindContainerRequest |
| | | { |
| | | ContainerCode = dto.PalletCode, |
| | | EquipmentCode = equipmentCode, |
| | | ResourceCode = resourceCode, |
| | | LocalTime = DateTime.Now, |
| | | OperationType = StockConstants.MES_BIND_OPERATION_TYPE, |
| | | ContainerSfcList = dto.Cells.Select((cell, i) => new ContainerSfcItem |
| | | { |
| | | Sfc = cell.SfcCode, |
| | | Location = cell.Channel |
| | | }).ToList() |
| | | }; |
| | | var mesResult = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.BindContainer(bindRequest) |
| | | : _mesService.BindContainer(bindRequest, token); |
| | | if (!CheckMesResult(mesResult, out var mesError)) |
| | | return WebResponseContent.Instance.Error($"MESç»çç»å®å¤±è´¥: {mesError}"); |
| | | |
| | | // 4. å建å
¥åºä»»å¡å¹¶ä¸åWCS |
| | | return await CreateTaskAndDispatchAsync(dto, warehouseId, targetAddress, roadway, |
| | | TaskInboundTypeEnum.Inbound, "ç»çæåå¹¶å建å
¥åºä»»å¡"); |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ§è¡æçæä½ï¼æ¥è¯¢åºå â ç´æ¥è°ç¨MESè§£ç» â æ¸
é¤åºåè´§ä½ â å建空æçå
¥åºä»»å¡ â ä¸åWCS |
| | | /// </summary> |
| | | private async Task<WebResponseContent> ExecuteSplitPalletAsync( |
| | | PalletOperationTaskDto dto, int warehouseId, string targetAddress, string roadway) |
| | | { |
| | | return await _unitOfWorkManage.BeginTranAsync(async () => |
| | | { |
| | | // 1. å¯¼èªæ¥è¯¢åºååæç» |
| | | var stockInfo = await _stockInfoService.Repository |
| | | .QueryDataNavFirstAsync(s => s.PalletCode == dto.PalletCode); |
| | | if (stockInfo == null) |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°æç[{dto.PalletCode}]çåºåè®°å½"); |
| | | |
| | | var sfcList = stockInfo.Details?.Select(d => d.SerialNumber).ToList() |
| | | ?? new List<string>(); |
| | | if (!sfcList.Any()) |
| | | return WebResponseContent.Instance.Error($"æç[{dto.PalletCode}]䏿 çµè¯æ°æ®"); |
| | | |
| | | // 2. è°ç¨MESè§£ç» |
| | | var (equipmentCode, resourceCode, token) = ResolveMesConfig(dto.RobotName); |
| | | var unbindRequest = new UnBindContainerRequest |
| | | { |
| | | EquipmentCode = equipmentCode, |
| | | ResourceCode = resourceCode, |
| | | LocalTime = DateTime.Now, |
| | | ContainCode = dto.PalletCode, |
| | | SfcList = sfcList |
| | | }; |
| | | var mesResult = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.UnBindContainer(unbindRequest) |
| | | : _mesService.UnBindContainer(unbindRequest, token); |
| | | if (!CheckMesResult(mesResult, out var mesError)) |
| | | return WebResponseContent.Instance.Error($"MESæçè§£ç»å¤±è´¥: {mesError}"); |
| | | |
| | | // 3. æ¸
é¤åºåç»å®çè´§ä½ |
| | | stockInfo.LocationId = 0; |
| | | stockInfo.LocationCode = null; |
| | | await _sqlSugarClient.Updateable(stockInfo) |
| | | .UpdateColumns(s => new { s.LocationId, s.LocationCode }) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // 4. å建空æçå
¥åºä»»å¡å¹¶ä¸åWCS |
| | | return await CreateTaskAndDispatchAsync(dto, warehouseId, targetAddress, roadway, |
| | | TaskInboundTypeEnum.InEmpty, "æçæåå¹¶å建空æçå
¥åºä»»å¡"); |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è§£æMES设å¤é
ç½®ï¼è¿å (equipmentCode, resourceCode, token) |
| | | /// </summary> |
| | | private (string equipmentCode, string resourceCode, string token) ResolveMesConfig(string deviceName) |
| | | { |
| | | var config = _mesDeviceConfigService.GetByDeviceName(deviceName); |
| | | return ( |
| | | config?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE, |
| | | config?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE, |
| | | config?.Token |
| | | ); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ£æ¥MESè¿åç»æï¼å¤±è´¥æ¶éè¿ error è¾åºéè¯¯ä¿¡æ¯ |
| | | /// </summary> |
| | | private bool CheckMesResult(HttpResponseResult<MesResponse> result, out string error) |
| | | { |
| | | if (result?.Data != null && result.Data.IsSuccess) |
| | | { |
| | | error = null; |
| | | return true; |
| | | } |
| | | |
| | | error = result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误"; |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å建å
¥åºä»»å¡å¹¶ä¸åWCS |
| | | /// </summary> |
| | | private async Task<WebResponseContent> CreateTaskAndDispatchAsync( |
| | | PalletOperationTaskDto dto, int warehouseId, string targetAddress, string roadway, |
| | | TaskInboundTypeEnum taskType, string successMessage) |
| | | { |
| | | int taskNum = await BaseDal.GetTaskNo(); |
| | | var task = new Dt_Task |
| | | { |
| | | TaskNum = taskNum, |
| | | PalletCode = dto.PalletCode, |
| | | SourceAddress = dto.LineId, |
| | | TargetAddress = targetAddress, |
| | | TaskType = taskType.GetHashCode(), |
| | | TaskStatus = TaskInStatusEnum.InNew.GetHashCode(), |
| | | Grade = dto.Grade, |
| | | Roadway = roadway, |
| | | WarehouseId = warehouseId, |
| | | CurrentAddress = dto.LineId, |
| | | NextAddress = targetAddress, |
| | | Creater = "manual", |
| | | CreateDate = DateTime.Now, |
| | | ModifyDate = DateTime.Now |
| | | }; |
| | | |
| | | if (await BaseDal.AddDataAsync(task) <= 0) |
| | | return WebResponseContent.Instance.Error("å建任å¡å¤±è´¥"); |
| | | |
| | | var wmsTaskDto = new WMSTaskDTO |
| | | { |
| | | TaskNum = task.TaskNum, |
| | | PalletCode = task.PalletCode, |
| | | SourceAddress = task.SourceAddress, |
| | | TargetAddress = task.TargetAddress, |
| | | TaskType = task.TaskType, |
| | | Roadway = task.Roadway, |
| | | TaskStatus = task.TaskStatus, |
| | | WarehouseId = task.WarehouseId |
| | | }; |
| | | |
| | | var wcsResult = _httpClientHelper.Post<WebResponseContent>( |
| | | "http://localhost:9292/api/Task/ReceiveManualTask", |
| | | new List<WMSTaskDTO> { wmsTaskDto }.ToJson()); |
| | | |
| | | if (!wcsResult.IsSuccess || !wcsResult.Data.Status) |
| | | return WebResponseContent.Instance.Error( |
| | | $"ä»»å¡å·²å建ä½åéç»WCS失败: {wcsResult.ErrorMessage}\r\n {wcsResult.Data?.Message}"); |
| | | |
| | | return WebResponseContent.Instance.OK($"{successMessage}ï¼ä»»å¡å·: {taskNum}"); |
| | | } |
| | | |
| | | #endregion æå¨ä»»å¡ |
| | | } |
| | | } |