| | |
| | | |
| | | using Mapster; |
| | | using Masuit.Tools; |
| | | using WIDESEA_Core.Const; |
| | | using WIDESEA_DTO.MOM; |
| | | using WIDESEA_DTO.WMS; |
| | | using WIDESEA_IServices; |
| | | using WIDESEA_IStoragIntegrationServices; |
| | | using WIDESEA_Services; |
| | | using WIDESEA_StorageBasicRepository; |
| | | using WIDESEAWCS_BasicInfoRepository; |
| | | using WIDESEAWCS_Model.Models; |
| | | |
| | | namespace WIDESEA_StorageOutTaskServices; |
| | | namespace WIDESEA_StorageTaskServices; |
| | | |
| | | public partial class Dt_TaskService : ServiceBase<Dt_Task, IDt_TaskRepository>, IDt_TaskService |
| | | { |
| | |
| | | var loation = _locationRepository.QueryFirst(x => x.RoadwayNo == task.Roadway && x.LocationCode == task.TargetAddress); |
| | | if (loation == null) |
| | | throw new Exception("未找到对应位置信息"); |
| | | var area = _areaInfoRepository.QueryFirst(x => x.AreaID == loation.AreaId); |
| | | |
| | | var area = new Dt_AreaInfo(); |
| | | var station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == task.SourceAddress); |
| | | if (station.stationPLC == "1017") |
| | | area = _areaInfoRepository.QueryFirst(x => x.AreaID == Convert.ToInt32(station.stationNGLocation)); |
| | | else |
| | | area = _areaInfoRepository.QueryFirst(x => x.AreaID == loation.AreaId); |
| | | if (area == null) |
| | | throw new Exception("未找到对应区域信息"); |
| | | var boxDetail = boxing.BoxingInfoDetails.Adapt<List<DtStockInfoDetail>>(); |
| | |
| | | { |
| | | return await CompleteInToOutTaskAsync(task); |
| | | } |
| | | |
| | | // 验证库存是否存在 |
| | | var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode); |
| | | |
| | |
| | | |
| | | #region 请求任务入库 |
| | | |
| | | #region |
| | | /// <summary> |
| | | /// 请求任务巷道 |
| | | /// </summary> |
| | | /// <param name="input">请求模型</param> |
| | | /// <returns>包含任务信息的响应内容</returns> |
| | | public async Task<WebResponseContent> RequestTaskAsync(RequestTaskDto input) |
| | | public async Task<WebResponseContent> RequestTaskAsync2(RequestTaskDto input) |
| | | { |
| | | // 创建一个WebResponseContent对象 |
| | | WebResponseContent content = new WebResponseContent(); |
| | |
| | | { |
| | | Software = area.Spare3, |
| | | TrayBarcode = input.PalletCode, |
| | | //EquipmentCode = "EQ_CWJZ01" |
| | | EquipmentCode = area.Spare2 |
| | | EquipmentCode = area.Spare2, |
| | | SceneType = area.Spare4, |
| | | }; |
| | | |
| | | // 调用GetTrayCellStatusAsync方法,获取整盘电芯 |
| | |
| | | return content.Error(result.MOMMessage); |
| | | |
| | | // 获取异常电芯 |
| | | var serialNosError = result.SerialNos.Where(x => x.SerialNoStatus != 1).ToList(); |
| | | List<SerialNoDto>? serialNosError = result.SerialNos.Where(x => x.SerialNoStatus != 1).ToList(); |
| | | if (serialNosError.Count > 0) |
| | | { |
| | | // TODO 创建任务送至NG排出口 |
| | |
| | | content = await RequestTrayInTaskAsync(input); |
| | | return content; |
| | | } |
| | | //Console.WriteLine("qqqqq"); |
| | | |
| | | // TODO 获取本地料框属性与整盘电芯属性获取的值进行对比,如果一致则继续,否则返回错误信息 |
| | | //var productions = await _productionRepository.QueryDataAsync(x => result.TrayBarcodePropertys.Select(x => x.TrayBarcodeProperty).ToList().Contains(x.TrayBarcodeProperty)); |
| | | //if (productions.Count <= 0) |
| | | // return content.Error("料框属性不存在"); |
| | | |
| | | // 调用CreateBoxingInfo方法,创建组盘信息 |
| | | |
| | | var boxing = CreateBoxingInfo(result, input.PalletCode); |
| | | //Console.WriteLine(boxing.ToJsonString()); |
| | | if (boxing == null) return content.Error("组盘失败"); |
| | | |
| | | // 调用GetProcessApplyAsync方法,获取工艺路线 |
| | | ProcessApplyDto process = await GetProcessApplyAsync(result); |
| | | |
| | | // 如果process为null,则返回content |
| | | if (process == null) return content; |
| | | |
| | | // 并赋值上位软件名称和设备编码 |
| | | process.Software = area.Spare3; |
| | | process.EquipmentCode = area.Spare2; |
| | | |
| | | // 调用GetProcessApplyAsync方法,获取工艺申请 |
| | | |
| | | // 调用_processApplyService.GetProcessApplyAsync方法,获取工艺申请 |
| | | content = await _processApplyService.GetProcessApplyAsync(process); |
| | | |
| | | // 如果状态为false,则返回null |
| | | if (!content.Status) return content.Error("工艺申请失败"); |
| | | var resultProcessApply = JsonConvert.DeserializeObject<ResultProcessApply>(content.Data.ToString()); |
| | | if ((resultProcessApply.Success)) return content.Error("工艺申请失败"); |
| | | |
| | | var par = resultProcessApply.ProcessInfo.Where(x => x.ProcessCode == boxing.ProcessCode).FirstOrDefault().Number.ToInt32(); |
| | | |
| | | |
| | | // 调用GetProcessResponseAsync方法,获取工艺响应 |
| | | //var processResponse = await GetProcessResponseAsync(process, input.Position); |
| | | |
| | | ////List<string> strings = input.Position == "1088" ? new List<string>() { "CHSC01" } : new List<string>() { "JZSC01" }; |
| | | Console.WriteLine(area.AreaCode+"-----------------------"); |
| | | Console.WriteLine(input.Position + "-----------------------"); |
| | | var stationManagers = _stationManagerRepository.QueryData(x => x.stationType == 1 && x.stationChildCode == input.Position && x.stationArea == area.AreaCode).ToList(); |
| | | if (stationManagers.Count <= 0) |
| | | if (result.ProcessCode == "OCVB") |
| | | { |
| | | throw new Exception("未找到NG入库站台配置"); |
| | | //TODO 判断需不需要去包装,不需要就去常温三 |
| | | var stationManagers = _stationManagerRepository.QueryData(x => x.stationPLC == "1018" && x.stationArea == "Cache"); |
| | | var station = stationManagers.Select(x => x.stationChildCode).ToList(); |
| | | |
| | | // 获取WCSip地址 |
| | | var configz = _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); |
| | | var wcsBasez = configz.Where(x => x.ConfigKey == SysConfigConst.WCSIPAddress).FirstOrDefault()?.ConfigValue; |
| | | var address = configz.Where(x => x.ConfigKey == SysConfigConst.GetStation).FirstOrDefault()?.ConfigValue; |
| | | if (wcsBasez == null || address == null) |
| | | { |
| | | throw new InvalidOperationException("WCS IP 未配置"); |
| | | } |
| | | var wcsIpAddrss = wcsBasez + address; |
| | | |
| | | var abc = HttpHelper.PostAsync(wcsIpAddrss, station.ToJsonString()).Result; |
| | | content = JsonConvert.DeserializeObject<WebResponseContent>(abc); |
| | | if (content.Data.ObjToInt() > 0) |
| | | { |
| | | // TODO 送至包装 |
| | | List<string> strings = stationManagers.Where(x => x.stationType == 0).Select(x => x.Roadway).ToList(); |
| | | content = await CreateNewTask(input, strings, 3); |
| | | return content; |
| | | } |
| | | else |
| | | { |
| | | var config = _configService.GetByConfigKey("SYS_InStacker", "CW3InStacker"); |
| | | var strings = config.ConfigValue.Split(',').ToList(); |
| | | // TODO 入库 |
| | | content = await CreateNewTask(input, strings); |
| | | if (content.Status) |
| | | await _boxingInfoRepository.AddDataNavAsync(boxing); |
| | | } |
| | | } |
| | | List<string> strings = stationManagers.Select(x => x.Roadway).ToList(); |
| | | //// 调用CreateNewTask方法,创建新任务 |
| | | content = await CreateNewTask(input, strings); |
| | | if (content.Status) |
| | | else |
| | | { |
| | | var isBox = await _boxingInfoRepository.AddDataNavAsync(boxing); |
| | | // TODO 获取本地料框属性与整盘电芯属性获取的值进行对比,如果一致则继续,否则返回错误信息 |
| | | //var productions = await _productionRepository.QueryDataAsync(x => result.TrayBarcodePropertys.Select(x => x.TrayBarcodeProperty).ToList().Contains(x.TrayBarcodeProperty)); |
| | | //if (productions.Count <= 0) |
| | | // return content.Error("料框属性不存在"); |
| | | |
| | | // 调用CreateBoxingInfo方法,创建组盘信息 |
| | | |
| | | //var boxing = CreateBoxingInfo(result, input.PalletCode); |
| | | ////Console.WriteLine(boxing.ToJsonString()); |
| | | //if (boxing == null) return content.Error("组盘失败"); |
| | | |
| | | // 调用GetProcessApplyAsync方法,获取工艺路线 |
| | | ProcessApplyDto process = await GetProcessApplyAsync(result); |
| | | |
| | | // 如果process为null,则返回content |
| | | if (process == null) return content; |
| | | |
| | | // 并赋值上位软件名称和设备编码 |
| | | process.Software = area.Spare3; |
| | | process.EquipmentCode = area.Spare2; |
| | | |
| | | // 调用GetProcessApplyAsync方法,获取工艺申请 |
| | | |
| | | // 调用_processApplyService.GetProcessApplyAsync方法,获取工艺申请 |
| | | content = await _processApplyService.GetProcessApplyAsync(process); |
| | | |
| | | // 如果状态为false,则返回null |
| | | if (!content.Status) return content.Error("工艺申请失败"); |
| | | |
| | | var resultProcessApply = JsonConvert.DeserializeObject<ResultProcessApply>(content.Data.ToString()); |
| | | if (!resultProcessApply.Success) return content.Error("工艺申请失败"); |
| | | |
| | | var number = resultProcessApply.ProcessInfo.Where(x => x.ProcessCode == boxing.ProcessCode).FirstOrDefault().Number.ToInt32(); |
| | | foreach (var item in resultProcessApply.ProcessInfo) |
| | | { |
| | | if (item.Number.ToInt32() == number + 1) |
| | | { |
| | | boxing.NextProcessCode = item.ProcessCode; |
| | | } |
| | | } |
| | | Console.WriteLine(); |
| | | Console.WriteLine($"当前工序:{boxing.ProcessCode}"); |
| | | Console.WriteLine($"下一工序:{boxing.NextProcessCode}"); |
| | | |
| | | Console.WriteLine(area.AreaCode + "-----------------------"); |
| | | Console.WriteLine(input.Position + "-----------------------"); |
| | | |
| | | var areaIn = string.Empty; |
| | | switch (boxing.NextProcessCode) |
| | | { |
| | | case "CH01": |
| | | areaIn = "CH001"; |
| | | break; |
| | | case "JZ01": |
| | | areaIn = "JZ001"; |
| | | break; |
| | | case "GW01": |
| | | areaIn = "GWSC1"; |
| | | break; |
| | | case "CW01": |
| | | areaIn = "CWSC1"; |
| | | break; |
| | | case "CW02": |
| | | areaIn = "CWSC2"; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | var stationManagers = _stationManagerRepository.QueryData(x => x.stationType == 1 && x.stationChildCode == input.Position && x.stationArea.Contains(areaIn)).FirstOrDefault(); |
| | | if (stationManagers == null) |
| | | { |
| | | throw new Exception("未找到入库站台配置"); |
| | | } |
| | | List<string> strings = stationManagers.Roadway.Split(',').ToList(); |
| | | Console.WriteLine(strings.ToJsonString() + "b-----------------------"); |
| | | //// 调用CreateNewTask方法,创建新任务 |
| | | content = await CreateNewTask(input, strings); |
| | | if (content.Status) |
| | | { |
| | | var isBox = await _boxingInfoRepository.AddDataNavAsync(boxing); |
| | | } |
| | | //} |
| | | } |
| | | } |
| | | catch (Exception err) |
| | |
| | | return content; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | public async Task<WebResponseContent> RequestTaskAsync(RequestTaskDto input) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | |
| | | try |
| | | { |
| | | // 查询任务 |
| | | var task = await QueryTaskByPalletCode(input.PalletCode); |
| | | if (task != null) |
| | | { |
| | | return CreateAndReturnWMSTaskDTO(task); |
| | | } |
| | | |
| | | // 查询库存信息(这里后续要完善质检回库逻辑) |
| | | var stock = await QueryStockInfo(input.PalletCode); |
| | | if (stock != null) |
| | | { |
| | | // TODO质检回库 |
| | | } |
| | | |
| | | // 根据位置查询区域信息 |
| | | var area = await QueryAreaInfoByPosition(input.Position); |
| | | if (area == null) |
| | | { |
| | | return content.Error("该点位不在区域列表中存在"); |
| | | } |
| | | |
| | | // 创建并获取整盘电芯状态 |
| | | TrayCellsStatusDto trayCells = CreateTrayCellsStatusDto(area, input.PalletCode); |
| | | content = await GetTrayCellStatusAsync(trayCells); |
| | | if (!content.Status) return content; |
| | | |
| | | var result = JsonConvert.DeserializeObject<ResultTrayCellsStatus>(content.Data.ToString()); |
| | | if (!result.Success) |
| | | { |
| | | return content.Error(result.MOMMessage); |
| | | } |
| | | |
| | | // 处理异常电芯情况 |
| | | var serialNosError = result.SerialNos.Where(x => x.SerialNoStatus != 1).ToList(); |
| | | if (serialNosError.Count > 0) |
| | | { |
| | | return await HandleErrorCells(input, area, serialNosError); |
| | | } |
| | | |
| | | if (result.SerialNos.Count <= 0) |
| | | { |
| | | // 空托盘入库逻辑 |
| | | return await RequestTrayInTaskAsync(input); |
| | | } |
| | | |
| | | var boxing = CreateBoxingInfo(result, input.PalletCode); |
| | | if (boxing == null) return content.Error("组盘失败"); |
| | | |
| | | return await ProcessBasedOnProcessCode(boxing, area, input, result); |
| | | } |
| | | catch (Exception err) |
| | | { |
| | | // 更详细的异常处理,可以根据异常类型记录不同的错误日志等 |
| | | content.Error(err.Message); |
| | | Console.WriteLine(err.Message); |
| | | } |
| | | |
| | | return content; |
| | | } |
| | | /// <summary> |
| | | /// 更新任务货位 |
| | | /// </summary> |
| | |
| | | return content.OK(data: task); |
| | | } |
| | | |
| | | var stationManagers = _stationManagerRepository.QueryData(x => x.stationType == 1 && x.stationChildCode == input.Position).ToList(); |
| | | if (stationManagers.Count <= 0) |
| | | |
| | | var stationManagers = _stationManagerRepository.QueryData(x => x.stationType == 6 && x.stationChildCode == input.Position).FirstOrDefault(); |
| | | if (stationManagers == null) |
| | | { |
| | | throw new Exception("未找到空托盘入库站台配置"); |
| | | stationManagers = _stationManagerRepository.QueryData(x => x.stationType == 1 && x.stationChildCode == input.Position).FirstOrDefault(); |
| | | if (stationManagers == null) |
| | | throw new Exception("未找到空托盘入库站台和入库站台配置"); |
| | | } |
| | | |
| | | |
| | | // 获取目标地址 |
| | | List<string> strings = stationManagers.Select(x => x.Roadway).ToList(); |
| | | List<string> strings = stationManagers.Roadway.Split(',').ToList(); |
| | | Console.WriteLine(strings.ToJsonString() + "b-----------------------"); |
| | | |
| | | return await CreateNewTask(input, strings, 1); |
| | | } |
| | |
| | | /// 创建新任务 |
| | | /// </summary> |
| | | /// <param name="input">请求模型</param> |
| | | /// <param name="areaId">区域ID</param> |
| | | /// <param name="content">响应内容</param> |
| | | /// <param name="process">巷道</param> |
| | | /// <param name="flag">标识(0-入库,1-空托盘入库,2-NG入库,3-出库)</param> |
| | | /// <returns></returns> |
| | | private async Task<WebResponseContent> CreateNewTask(RequestTaskDto input, List<string> process = null, int flag = 0) |
| | | { |
| | |
| | | // 获取目标地址 |
| | | //string ToAddress = await GetRoadWayAsync(process); |
| | | string ToAddress = string.Empty; |
| | | if (flag != 2) |
| | | ToAddress = await GetRoadWayAsync(input, process); |
| | | if (flag < 2) |
| | | ToAddress = await GetRoadWayAsync(process); |
| | | else |
| | | ToAddress = process[0]; |
| | | |
| | |
| | | OrderNo = null, |
| | | PalletCode = input.PalletCode, |
| | | SourceAddress = input.Position, |
| | | TaskState = (int)TaskInStatusEnum.InNew, |
| | | TaskType = flag == 0 ? (int)TaskInboundTypeEnum.Inbound : flag == 1 ? (int)TaskInboundTypeEnum.InTray : (int)TaskInboundTypeEnum.InNG, |
| | | TaskState = flag == 3 ? (int)TaskOutStatusEnum.OutNew : (int)TaskInStatusEnum.InNew, |
| | | TaskType = flag == 0 ? (int)TaskInboundTypeEnum.Inbound : flag == 1 ? (int)TaskInboundTypeEnum.InTray : flag == 2 ? (int)TaskInboundTypeEnum.InNG : (int)TaskOutboundTypeEnum.Outbound, |
| | | TaskNum = await BaseDal.GetTaskNo(), |
| | | Creater = "Systeam" |
| | | }; |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取巷道或站台 |
| | | /// 根据巷道获取巷道或站台 |
| | | /// </summary> |
| | | /// <param name="areaId">货位区域ID</param> |
| | | /// <param name="position">站台</param> |
| | | /// <param name="Direction">方向</param> |
| | | /// <param name="area">关系区域</param> |
| | | /// <returns></returns> |
| | | public async Task<string> GetRoadWayAsync(RequestTaskDto input, List<string> process) |
| | | public async Task<string> GetRoadWayAsync(List<string> process) |
| | | { |
| | | var minGroup = _locationRepository.QueryData(x => process.Contains(x.RoadwayNo) && x.LocationStatus == (int)LocationEnum.Free) |
| | | .GroupBy(x => x.RoadwayNo) |
| | | .OrderByDescending(g => g.Count()) // 根据每个组的元素数量排序 |
| | | .First(); // 取出数量最多的组 |
| | | .ToList(); // 取出数量最多的组 |
| | | |
| | | string minRoadwayNo = minGroup.Key; // 数量最多的组的Key |
| | | Dictionary<string,int> result = new Dictionary<string,int>(); |
| | | foreach (var item in minGroup) |
| | | { |
| | | var number = BaseDal.QueryData(x => x.TargetAddress == item.Key).Count(); |
| | | result.Add(item.Key, item.Count() - number); |
| | | } |
| | | |
| | | string minRoadwayNo = result.OrderByDescending(x => x.Value).FirstOrDefault().Key; // 数量最多的组的Key |
| | | |
| | | return minRoadwayNo; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取巷道或站台 |
| | | /// 根据区域获取巷道或站台 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public async Task<string> GetRoadWayAsync(int areaCode) |
| | |
| | | var minGroup = _locationRepository.QueryData(x => x.AreaId == areaCode && x.LocationStatus == (int)LocationEnum.Free) |
| | | .GroupBy(x => x.RoadwayNo) |
| | | .OrderBy(g => g.Count()) // 根据每个组的元素数量排序 |
| | | .First(); // 取出数量最少的组 |
| | | .ToList(); // 取出数量最少的组 |
| | | |
| | | string minRoadwayNo = minGroup.Key; // 数量最少的组的Key |
| | | Dictionary<string, int> result = new Dictionary<string, int>(); |
| | | foreach (var item in minGroup) |
| | | { |
| | | var number = BaseDal.QueryData(x => x.TargetAddress == item.Key).Count(); |
| | | result.Add(item.Key, item.Count() - number); |
| | | } |
| | | |
| | | string minRoadwayNo = result.OrderByDescending(x => x.Value).FirstOrDefault().Key; // 数量最多的组的Key |
| | | |
| | | return minRoadwayNo; |
| | | } |