| | |
| | | } |
| | | } |
| | | |
| | | public async Task<WebResponseContent> CompleteNgTaskAsync(Dt_Task task) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | try |
| | | { |
| | | var boxing = await _boxingInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode); |
| | | if (boxing != null) |
| | | { |
| | | await _boxingInfoRepository.Db.DeleteNav<DtBoxingInfo>(x => x.Id == boxing.Id) |
| | | .Include(x => x.BoxingInfoDetails) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | var loc = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress && x.RoadwayNo == task.Roadway); |
| | | var taskHty = task.Adapt<Dt_Task_Hty>(); |
| | | taskHty.FinishTime = DateTime.Now; |
| | | taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; |
| | | taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; |
| | | int lastStatus = loc.LocationStatus; |
| | | loc.LocationStatus = (int)LocationEnum.Free; |
| | | task.TaskState = (int)TaskOutStatusEnum.OutFinish; |
| | | // 事务处理 |
| | | await _unitOfWorkManage.UseTranAsync(async () => |
| | | { |
| | | await UpdateLocationAsync(loc); |
| | | |
| | | await DeleteTaskAsync(task.TaskId); |
| | | await AddTaskHtyAsync(taskHty); |
| | | }); |
| | | |
| | | _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(loc, lastStatus, (int)StatusChangeTypeEnum.AutomaticDelivery, task.TaskNum); |
| | | return content.OK("任务完成成功", task.Remark); |
| | | } |
| | | catch (Exception err) |
| | | { |
| | | LogFactory.GetLog("任务完成").Error(true, $"系统异常,异常信息:{err.Message}"); |
| | | return content.Error(err.Message); |
| | | } |
| | | } |
| | | |
| | | private AgingOutputDto MapToAgingOutputDto(DtStockInfo stock, ResponseEqptRunDto? info = null) |
| | | { |
| | | // TODO Value值根据MOM下发的静置时间到当前时间的分钟数 |
| | |
| | | return content.OK("入库任务完成成功"); |
| | | } |
| | | // 根据是否有组盘信息创建库存实例模型 |
| | | DtStockInfo stock = boxing == null ? CreateEmptyPalletStock(task, locationInf) : CreateFullPalletStock(task, locationInf, boxing); |
| | | DtStockInfo stock = null; |
| | | if (boxing == null && task.TaskType == (int)TaskInboundTypeEnum.InTray) |
| | | { |
| | | stock = CreateEmptyPalletStock(task, locationInf); |
| | | } |
| | | else |
| | | { |
| | | stock = CreateFullPalletStock(task, locationInf, boxing); |
| | | } |
| | | |
| | | // 执行数据库事务 |
| | | bool isResult = await ExecuteTransaction(stock, taskHty, locationInf, task.TaskId, boxing); |
| | |
| | | |
| | | case (int)TaskOutboundTypeEnum.OutTray: |
| | | case (int)TaskOutboundTypeEnum.Outbound: |
| | | case (int)TaskOutboundTypeEnum.OutNG: |
| | | |
| | | LogFactory.GetLog("任务完成").InfoFormat(true, "出库任务", ""); |
| | | return await CompleteStackTaskAsync(task, stock); |
| | | |
| | | case (int)TaskOutboundTypeEnum.OutNG: |
| | | LogFactory.GetLog("任务完成").InfoFormat(true, "出库任务", ""); |
| | | if(task.Roadway.Contains("FR")) |
| | | { |
| | | return await CompleteStackTaskAsync(task, stock); |
| | | } |
| | | else |
| | | { |
| | | return await CompleteNgTaskAsync(task); |
| | | } |
| | | case (int)TaskOutboundTypeEnum.OutFireAlarm: |
| | | |
| | | LogFactory.GetLog("任务完成").InfoFormat(true, "火警任务", ""); |
| | |
| | | { |
| | | return CreateAndReturnWMSTaskDTO(task); |
| | | } |
| | | if(task != null && (task.TaskState != (int)TaskInStatusEnum.InNew || task.TaskState != (int)TaskOutStatusEnum.OutNew)) |
| | | if (task != null && (task.TaskState != (int)TaskInStatusEnum.InNew || task.TaskState != (int)TaskOutStatusEnum.OutNew)) |
| | | { |
| | | return content.Error($"托盘{input.PalletCode}存在任务"); |
| | | } |
| | |
| | | ConsoleHelper.WriteErrorLine($"获取电芯状态失败:{result.MOMMessage}"); |
| | | if (result.SerialNos.Count <= 0) |
| | | { |
| | | var config = _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_InStacker, SysConfigConst.InboundIsEmpty); |
| | | var strings = config.ConfigValue.Split(',').ToList(); |
| | | if (strings.Contains(input.Position)) |
| | | { |
| | | // todo送至NG口 |
| | | ConsoleHelper.WriteErrorLine($"当前位置【{input.Position}】不能入空托盘"); |
| | | return content.Error($"当前位置【{input.Position}】不能入空托盘"); |
| | | } |
| | | // 空托盘入库逻辑 |
| | | var staion = _stationManagerRepository.QueryFirst(x => x.stationChildCode == input.Position && x.stationType == 1 && x.remark == "IN"); |
| | | if (staion != null) |
| | |
| | | if (strings.Contains(input.Position)) |
| | | { |
| | | // todo送至NG口 |
| | | ConsoleHelper.WriteErrorLine($"当前位置不能入空托盘"); |
| | | return content.Error("当前位置不能入空托盘"); |
| | | ConsoleHelper.WriteErrorLine($"当前位置【{input.Position}】不能入空托盘"); |
| | | return content.Error($"当前位置【{input.Position}】不能入空托盘"); |
| | | } |
| | | else |
| | | return await RequestTrayInTaskAsync(input); |
| | |
| | | } |
| | | |
| | | //var outBoundMateriel = AppSettings.app<OutBoundMateriel>("OutBoundMateriel"); |
| | | var outBoundMateriel = _dt_ChangeoversRepository.QueryData(x => x.Status == "1").ToList(); |
| | | //var outBoundMateriel = _dt_ChangeoversRepository.QueryData(x => x.Status == "1").ToList(); |
| | | |
| | | List<string>? materielCodes = outBoundMateriel.Count != 0 |
| | | ? outBoundMateriel.Where(x => x.ProductionLine == productionLine && x.ProcessCode == area.AreaCode) |
| | | .Select(x => x.MaterielCode) |
| | | .ToList() |
| | | : null; |
| | | //List<string>? materielCodes = outBoundMateriel.Count != 0 |
| | | // ? outBoundMateriel.Where(x => x.ProductionLine == productionLine && x.ProcessCode == area.AreaCode) |
| | | // .Select(x => x.MaterielCode) |
| | | // .ToList() |
| | | // : null; |
| | | |
| | | var result = new DtStockInfo(); |
| | | //DtStockInfo result = null; |
| | | |
| | | var stockInfoList = await _stockInfoRepository.Db.Queryable<DtStockInfo>() |
| | | var result = await _stockInfoRepository.Db.Queryable<DtStockInfo>() |
| | | .Includes(x => x.LocationInfo) |
| | | //.Includes(x => x.StockInfoDetails) |
| | | .Where(x => x.AreaCode == areaCode && x.OutboundTime < DateTime.Now && x.IsFull) |
| | |
| | | .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) |
| | | //.WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode))) |
| | | .OrderBy(x => x.OutboundTime) |
| | | .ToListAsync(); |
| | | foreach (var stock in stockInfoList) |
| | | { |
| | | var hasMatchingDetail = await _stockInfoRepository.Db.Queryable<DtStockInfoDetail>() |
| | | .Where(d => d.StockId == stock.Id && materielCodes.Contains(d.MaterielCode)) |
| | | .AnyAsync(); |
| | | .FirstAsync(); |
| | | //foreach (var stock in stockInfoList) |
| | | //{ |
| | | // var hasMatchingDetail = await _stockInfoRepository.Db.Queryable<DtStockInfoDetail>() |
| | | // .Where(d => d.StockId == stock.Id && materielCodes.Contains(d.MaterielCode)) |
| | | // .AnyAsync(); |
| | | |
| | | if (hasMatchingDetail) |
| | | { |
| | | result = stock; |
| | | break; |
| | | } |
| | | } |
| | | // if (hasMatchingDetail) |
| | | // { |
| | | // result = stock; |
| | | // break; |
| | | // } |
| | | //} |
| | | |
| | | if (result.IsNullOrEmpty()) |
| | | ConsoleHelper.WriteErrorLine($"{area.AreaName}-{productionLine}查询实盘库存信息失败:未找到符合条件的数据"); |
| | |
| | | ConsoleHelper.WriteErrorLine(content.ToJsonString()); |
| | | var result = JsonConvert.DeserializeObject<ResultTrayCellsStatus>(content.Data.ToString()); |
| | | if (result == null || !result.Success) return content.Error(result?.MOMMessage ?? "Deserialization error"); |
| | | |
| | | List<string> strings = station.productLine.Split(",").ToList(); |
| | | if (!result.ProductionLine.Contains(strings)) |
| | | { |
| | | ConsoleHelper.WriteErrorLine($"托盘号【{palletCode}】请求产线【{result.ProductionLine}】不允许入【{station.Roadway}】"); |
| | | return content.Error($"托盘号【{palletCode}】请求产线【{result.ProductionLine}】不允许入【{station.Roadway}】"); |
| | | } |
| | | |
| | | if (result.SerialNos.Count > 0) |
| | | { |
| | |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | |
| | | // 获取目标地址 |
| | | //string ToAddress = await GetRoadWayAsync(process); |
| | | string ToAddress = string.Empty; |
| | | if (flag < 2) |
| | | if (input.Position == "1039") |
| | | { |
| | | ToAddress = await GetGWRoadWayAsync(process); |
| | | } |
| | | else if (flag < 2) |
| | | { |
| | | ToAddress = await GetRoadWayAsync(process); |
| | | } |
| | | else |
| | | { |
| | | ToAddress = process[0]; |
| | | } |
| | | if (string.IsNullOrEmpty(ToAddress)) |
| | | { |
| | | return content.Error("无法获取目标地址"); |
| | |
| | | { |
| | | task.TaskId = taskId; |
| | | isResult = await _taskExecuteDetailRepository.AddDetailAsync(task, false, TaskDescription.GetTaskUpdateDescription(input.PalletCode, input.Position, ToAddress, TaskInStatusEnum.InNew.GetIntegralRuleTypeEnumDesc())); |
| | | |
| | | //var location = _locationRepository.QueryFirst(x => x.RoadwayNo == task.Roadway && x.LocationCode == task.TargetAddress); |
| | | //location.LocationStatus = (int)LocationEnum.Lock; |
| | | //var isLocation = _locationRepository.UpdateData(location); |
| | | |
| | | if (isResult) |
| | | { |
| | |
| | | .Where(x => x.DeviceStatus == 1.ToString() && process.Contains(x.DeviceCode)) |
| | | .Select(x => x.DeviceCode).ToListAsync(); |
| | | |
| | | var minGroup = _locationRepository.QueryData(x => deviceCode.Contains(x.RoadwayNo) && x.LocationStatus == (int)LocationEnum.Free) |
| | | var minGroup = _locationRepository.QueryData(x => deviceCode.Contains(x.RoadwayNo) && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == (int)EnableEnum.Enable) |
| | | .GroupBy(x => x.RoadwayNo) |
| | | .OrderByDescending(g => g.Count()) // 根据每个组的元素数量排序 |
| | | .ToList(); // 取出数量最多的组 |
| | |
| | | foreach (var item in minGroup) |
| | | { |
| | | var number = BaseDal.QueryData(x => x.TargetAddress == item.Key).Count(); |
| | | if (item.Count() - number <= 0) |
| | | { |
| | | continue; |
| | | } |
| | | result.Add(item.Key, item.Count() - number); |
| | | } |
| | | |
| | |
| | | return minRoadwayNo; |
| | | } |
| | | |
| | | |
| | | private static readonly object _lock = new object(); |
| | | private static int _currentIndex = -1; // 记录上一次分配的巷道索引 |
| | | public async Task<string> GetGWRoadWayAsync(List<string> process) |
| | | { |
| | | var deviceCode = await SqlSugarHelper.DbWCS.Queryable<Dt_DeviceInfo>() |
| | | .Where(x => x.DeviceStatus == 1.ToString() && process.Contains(x.DeviceCode)) |
| | | .Select(x => x.DeviceCode).ToListAsync(); |
| | | |
| | | var availableRoadways = _locationRepository.QueryData(x => deviceCode.Contains(x.RoadwayNo) && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == (int)EnableEnum.Enable) |
| | | .GroupBy(x => x.RoadwayNo) |
| | | .Select(g => new |
| | | { |
| | | RoadwayNo = g.Key, |
| | | Count = g.Count(), |
| | | TargetCount = BaseDal.QueryData(t => t.TargetAddress == g.Key).Count() |
| | | }) |
| | | .Where(x => x.Count - x.TargetCount > 0 && x.TargetCount < 2) |
| | | .OrderByDescending(x => x.Count) |
| | | .ToList(); |
| | | |
| | | if (!availableRoadways.Any()) |
| | | { |
| | | return null; // 或抛出异常 |
| | | } |
| | | |
| | | // 轮询分配 |
| | | lock (_lock) |
| | | { |
| | | _currentIndex = (_currentIndex + 1) % availableRoadways.Count; |
| | | return availableRoadways[_currentIndex].RoadwayNo; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据区域获取巷道或站台 |
| | | /// </summary> |