#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEA_TaskInfoService * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using Autofac.Core; using AutoMapper; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using SqlSugar; using System.DirectoryServices.Protocols; using System.Net; using System.Reflection.Emit; using System.Threading.Tasks; using WIDESEA_Common.LocationEnum; using WIDESEA_Common.OtherEnum; using WIDESEA_Common.StockEnum; using WIDESEA_Common.TaskEnum; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_Core.Const; using WIDESEA_Core.Enums; using WIDESEA_Core.Helper; using WIDESEA_DTO.Task; using WIDESEA_DTO.ToMes; using WIDESEA_IBasicService; using WIDESEA_IInboundService; using WIDESEA_IOutboundService; using WIDESEA_IRecordService; using WIDESEA_IStockService; using WIDESEA_ITaskInfoService; using WIDESEA_Model.Models; namespace WIDESEA_TaskInfoService { public partial class TaskService : ServiceBase>, ITaskService { private readonly IMapper _mapper; private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IRepository _stockRepository; private readonly IRepository _warehouseRepository; private readonly IRepository _locationInfoRepository; private readonly IRepository _roadwayInforepository; private readonly IBasicService _basicService; private readonly IDt_ApiInfoService _dt_ApiInfoService; private readonly ILocationStatusChangeRecordService _locationStatusChangeRecordService; private readonly IStationMangerService _stationMangerService; public IRepository Repository => BaseDal; private Dictionary _taskOrderBy = new() { {nameof(Dt_Task.Grade),OrderByType.Desc }, {nameof(Dt_Task.CreateDate),OrderByType.Asc}, }; public TaskService(IRepository BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository stockRepository, IBasicService basicService, IRepository warehouseRepository, IRepository locationInfoRepository, IRepository roadwayInforepository, IDt_ApiInfoService dt_ApiInfoService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IStationMangerService stationMangerService) : base(BaseDal) { _mapper = mapper; _unitOfWorkManage = unitOfWorkManage; _stockRepository = stockRepository; _basicService = basicService; _warehouseRepository = warehouseRepository; _locationInfoRepository = locationInfoRepository; _roadwayInforepository = roadwayInforepository; _dt_ApiInfoService = dt_ApiInfoService; _locationStatusChangeRecordService = locationStatusChangeRecordService; _stationMangerService=stationMangerService; } public int GetTaskNum(string sequenceName) { return Db.Ado.GetScalar($"SELECT NEXT VALUE FOR {sequenceName}").ObjToInt(); } /// /// 任务信息推送至WCS /// /// public WebResponseContent PushTasksToWCS(List tasks, string agvDescription = "") { try { List taskDTOs = _mapper.Map>(tasks); taskDTOs.ForEach(x => { x.AGVArea = agvDescription; }); var ConfigsAPIInfo = _dt_ApiInfoService.GetConfigsByAPIInfo(CateGoryConst.CONFIG_WCS_IPAddress, SysConfigConst.WCSReceiveTask); //获取到wcs全部类型的接口 string WCSReceiveTaskAPI = ConfigsAPIInfo.ApiAddress + ConfigsAPIInfo.ApiName; var respon = HttpHelper.Post(WCSReceiveTaskAPI, JsonConvert.SerializeObject(taskDTOs)); if (respon != null) { WebResponseContent respone = JsonConvert.DeserializeObject(respon.ToString()); if (respone.Status) { return WebResponseContent.Instance.OK(); } else { return WebResponseContent.Instance.Error($"下发出库失败,原因:{respone.Message}!"); } } else { return WebResponseContent.Instance.Error("任务下发失败!"); } } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } /// /// 判断巷道内移库 /// /// /// /// public WebResponseContent IsRelocations(int TaskNum) { WebResponseContent content = new WebResponseContent(); try { List loca = new List(); Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == TaskNum); if (task == null) return content.Error($"未找到该任务信息,任务号:{TaskNum}"); string Locatask = task.SourceAddress; //获取到深库位编号 Dt_LocationInfo DeepLocation = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == Locatask); if(DeepLocation == null) return content.Error($"未找到该货位信息,货位编号:{Locatask}"); //进行获取浅库位编号 int locrow = DeepLocation.Row == 1 ? 2 : 3; Dt_LocationInfo ShallowLocation = _basicService.LocationInfoService.Repository.QueryFirst(x =>x.Row== locrow && x.Layer== DeepLocation.Layer && x.Column== DeepLocation.Column && x.RoadwayNo== DeepLocation.RoadwayNo); if (ShallowLocation == null) return content.Error($"未找到货位编号:{Locatask}的浅货位"); if (ShallowLocation.LocationStatus == (int)LocationStatusEnum.Free) { return content.OK(data: task); //直接返回当前查询的任务 } //如果有货,则生成移库任务 if (ShallowLocation.LocationStatus == (int)LocationStatusEnum.InStock) { Dt_StockInfo dt_Stock = _stockRepository.QueryFirst(x => x.LocationCode == ShallowLocation.LocationCode); if (dt_Stock == null) return content.Error($"货位编号:{Locatask}的浅货位库存异常,请检查!!!"); //进行获取新的库位 Dt_LocationInfo? Nextlocation = _basicService.LocationInfoService.GetLocation(DeepLocation.RoadwayNo);//获取到新库位 if (Nextlocation == null) { return content.Error($"货位分配失败,未找到可分配货位"); } ShallowLocation.LocationStatus = (int)LocationStatusEnum.Lock; Nextlocation.LocationStatus = (int)LocationStatusEnum.Lock; loca.Add(ShallowLocation); loca.Add(Nextlocation); _unitOfWorkManage.BeginTran(); //生成移动任务 Dt_Task dt_Task = new() { PalletCode = dt_Stock.PalletCode, TaskNum = GetTaskNum(nameof(SequenceEnum.SeqTaskNum)), Roadway = Nextlocation.RoadwayNo, TaskType = TaskRelocationTypeEnum.Relocation.ObjToInt(), TaskStatus = TaskRelocationStatusEnum.RelocationNew.ObjToInt(), SourceAddress = ShallowLocation.LocationCode, TargetAddress = Nextlocation.LocationCode, CurrentAddress = ShallowLocation.LocationCode, NextAddress = Nextlocation.LocationCode, Grade = 1, Creater = "WMS", Depth = ShallowLocation.Depth, CreateDate = DateTime.Now, }; _locationInfoRepository.AddData(loca); BaseDal.AddData(dt_Task); //新增任务 _unitOfWorkManage.CommitTran(); return content.OK(data: dt_Task); } else { return content.Error($"货位编号:{Locatask}的浅货位状态异常,浅货位编号:{ShallowLocation.LocationCode}"); } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); throw; } } /// /// 任务完成 /// /// 任务编号 /// 模式(1:自动,2:手动) /// public WebResponseContent TaskCompleted(int taskNum) { WebResponseContent content = new WebResponseContent(); Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error("未找到任务信息"); switch (task.TaskType) { case (int)TaskRelocationTypeEnum.Relocation: return RelocationInTaskCompleted(task); case (int)TaskInboundTypeEnum.Inbound: return InboundTaskCompleted(task); case (int)TaskOutboundTypeEnum.Outbound: return OutboundTaskCompleted(task); default: return content.Error($"任务类型错误,任务号:{task.TaskNum}"); } } /// /// 移库完成方法 /// /// /// public WebResponseContent RelocationInTaskCompleted(Dt_Task task) { WebResponseContent webResponse = new WebResponseContent(); try { Dt_StockInfo stockInfo = _stockRepository.QueryFirst(x => x.PalletCode == task.PalletCode); Dt_LocationInfo locationpoint = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == task.SourceAddress); Dt_LocationInfo locationEnd = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress); List loca = new List(); stockInfo.LocationCode = locationEnd.LocationCode; stockInfo.StockStatus = StockStatusEmun.已入库.ObjToInt(); locationpoint.LocationStatus = LocationStatusEnum.Free.ObjToInt(); locationEnd.LocationStatus = LocationStatusEnum.InStock.ObjToInt(); loca.Add(locationpoint); loca.Add(locationEnd); _unitOfWorkManage.BeginTran(); _stockRepository.UpdateData(stockInfo); _basicService.LocationInfoService.Repository.UpdateData(loca); BaseDal.DeleteData(task); BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成); WebResponseContent content=MES_TransferCompletionFeedback(task); if (!content.Status) { _unitOfWorkManage.RollbackTran(); return content; } _unitOfWorkManage.CommitTran(); return webResponse.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return webResponse.Error($"移库任务完成失败,任务id:{task.TaskNum}"); throw; } } /// /// 入库任务完成 /// /// /// public WebResponseContent InboundTaskCompleted(Dt_Task task) { try { Dt_Warehouse warehouse = _warehouseRepository.QueryFirst(x => x.WarehouseId == task.WarehouseId); Dt_StockInfo stockInfo = _stockRepository.Db.Queryable().Where(x => x.PalletCode == task.PalletCode && x.WarehouseId == task.WarehouseId).First(); if (stockInfo == null) { return WebResponseContent.Instance.Error($"未找到托盘对应的组盘信息"); } //if (!string.IsNullOrEmpty(stockInfo.LocationCode)) //{ // return WebResponseContent.Instance.Error($"该托盘已绑定货位"); //} Dt_LocationInfo dt_LocationInfo = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress); if (dt_LocationInfo == null) { return WebResponseContent.Instance.Error("未找到库位"); } dt_LocationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt(); stockInfo.StockStatus = StockStatusEmun.入库完成.ObjToInt(); _unitOfWorkManage.BeginTran(); //修改货位状态为有货 _locationInfoRepository.UpdateData(dt_LocationInfo); //修改库存状态 _stockRepository.UpdateData(stockInfo); //删除任务添加历史 BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId > 0 ? OperateTypeEnum.人工完成 : OperateTypeEnum.自动完成); /*WebResponseContent content = TaskCompletionFeedback(task); if (!content.Status) { _unitOfWorkManage.RollbackTran(); return content; }*/ _unitOfWorkManage.CommitTran(); } catch (Exception) { _unitOfWorkManage.RollbackTran(); throw; } return WebResponseContent.Instance.OK(); } /// /// 出库任务完成 /// /// /// public WebResponseContent OutboundTaskCompleted(Dt_Task task) { WebResponseContent webResponse = new WebResponseContent(); try { Dt_StockInfo stockInfo = _stockRepository.QueryFirst(x => x.PalletCode == task.PalletCode); if (stockInfo == null) return webResponse.Error($"任务编号:{task.TaskNum},未找到托盘:{stockInfo.PalletCode}的库存信息"); Dt_LocationInfo locationInfo = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.SourceAddress); if (locationInfo == null) return webResponse.Error($"任务编号:{task.TaskNum},未找到托盘:{stockInfo.PalletCode}的货位信息"); stockInfo.StockStatus = StockStatusEmun.出库完成.ObjToInt(); int beforeStatus = locationInfo.LocationStatus; locationInfo.LocationStatus =(int)LocationStatusEnum.Free; task.TaskStatus = TaskOutStatusEnum.OutFinish.ObjToInt(); _unitOfWorkManage.BeginTran(); _stockRepository.DeleteData(stockInfo); _locationInfoRepository.UpdateData(locationInfo); //修改成空货位 BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成); _locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, beforeStatus, StockStatusEmun.出库完成.ObjToInt(), "1", task.TaskNum); /*WebResponseContent content = TaskCompletionFeedback(task); if (!content.Status) { _unitOfWorkManage.RollbackTran(); return content; }*/ _unitOfWorkManage.CommitTran(); return webResponse.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return webResponse.Error($"出库任务完成失败,任务id:{task.TaskNum},错误原因:{ex.Message}"); throw; } } //==============================================移库完成反馈接口==================================================== /// /// 上传移库任务完成给MES /// /// /// public WebResponseContent MES_TransferCompletionFeedback(Dt_Task dt_Task) { WebResponseContent webResponse = new WebResponseContent(); try { TransferRequest transferRequest = new TransferRequest() { //业务id,任务id后续进行更改 businessId = "1", TaskId = "1", SourceLocationCode = dt_Task.SourceAddress, LocationCode = dt_Task.TargetAddress, PalletCode = dt_Task.PalletCode, Status = "FINISH", ErrorStatus = "NORMAL", ErrorInfo = "", }; //获取接口进行调取 var ConfigsAPIInfo = _dt_ApiInfoService.GetConfigsByAPIInfo(CateGoryConst.CONFIG_MES_IPAddress, SysConfigConst.MESTransferCompletionFeedback); //获取到wcs全部类型的接口 string WCSReceiveTaskAPI = ConfigsAPIInfo.ApiAddress + ConfigsAPIInfo.ApiName; if (WCSReceiveTaskAPI == null) { return webResponse.Error($"出库失败,未配置MES移库完成反馈接口"); } var respon = HttpHelper.Post(WCSReceiveTaskAPI, JsonConvert.SerializeObject(transferRequest)); if (respon != null) { var response = JsonConvert.DeserializeObject>(respon); if (response.Success) { return webResponse.OK(); } else { return webResponse.Error($"调取接口失败,反馈参数原因:{response.Message}"); } } else { return webResponse.Error($"调取接口失败,反馈参数为空"); } } catch (Exception ex) { return webResponse.Error($"移库任务上传失败!原因:{ex.Message}"); throw; } } /// /// 上传出入库任务完成给MES /// /// /// public WebResponseContent TaskCompletionFeedback(Dt_Task dt_Task) { WebResponseContent webResponse = new WebResponseContent(); try { TaskNotification transferRequest = new TaskNotification() { //业务id,任务id后续进行更改 TaskId = "1", //任务id BusinessId = "1", //业务id PalletCode = dt_Task.PalletCode, SubPalletCode = "",//子托盘编码 LocationCode = dt_Task.SourceAddress, ErrorStatus = "NORMAL", ErrorInfo = "", }; //获取接口进行调取 var ConfigsAPIInfo = _dt_ApiInfoService.GetConfigsByAPIInfo(CateGoryConst.CONFIG_MES_IPAddress, SysConfigConst.MESTaskFeedback); //获取到wcs全部类型的接口 string WCSReceiveTaskAPI = ConfigsAPIInfo.ApiAddress + ConfigsAPIInfo.ApiName; if (WCSReceiveTaskAPI == null) { return webResponse.Error($"任务反馈MES失败,未配置MES任务完成反馈接口"); } var respon = HttpHelper.Post(WCSReceiveTaskAPI, JsonConvert.SerializeObject(transferRequest)); if (respon != null) { var response = JsonConvert.DeserializeObject>(respon); if (response.Success) { return webResponse.OK(); } else { return webResponse.Error($"调取接口失败,反馈参数原因:{response.Message}"); } } else { return webResponse.Error($"调取接口失败,反馈参数为空"); } } catch (Exception ex) { return webResponse.Error($"任务任务上传失败!原因:{ex.Message}"); throw; } } public ApiResponse MESresponse(string Message, bool Success) { ApiResponse apiResponse = new ApiResponse(); apiResponse.Message = Message; apiResponse.Success = Success; apiResponse.Code = 1; return apiResponse; } /// /// 创建货位 /// /// /// /// public ApiResponse createLocation(List locationInfo) { List dt_LocationInfoList = new List(); foreach (var item in locationInfo) { Dt_LocationInfo dt_LocationInfo = new Dt_LocationInfo() { LocationCode = item.locationCode, LocationName = item.locationName, RoadwayNo = item.roadwayNo, Row = item.row, Column = item.column, Layer = item.layer, Depth = (int)item.depth, LocationType = item.locationType, LocationStatus = item.locationStatus, EnableStatus = item.enableStatus == true ? 1 : 0, Remark = item.remark, CreateDate = DateTime.Now, Creater = App.User.UserName, }; dt_LocationInfoList.Add(dt_LocationInfo); } int res = _locationInfoRepository.AddData(dt_LocationInfoList); if (res <= 0) { return MESresponse($"创建货位失败",false); } return MESresponse($"", true); } /// /// 修改货位 /// /// /// /// public ApiResponse updateLocation(LocationInfoDto locationInfo) { Dt_LocationInfo dt_LocationInfo = new Dt_LocationInfo() { LocationCode = locationInfo.locationCode, LocationName = locationInfo.locationName, RoadwayNo = locationInfo.roadwayNo, Row = locationInfo.row, Column = locationInfo.column, Layer = locationInfo.layer, Depth = (int)locationInfo.depth, LocationType = locationInfo.locationType, LocationStatus = locationInfo.locationStatus, EnableStatus = locationInfo.enableStatus == true ? 1 : 0, Remark = locationInfo.remark, CreateDate = DateTime.Now, }; bool res = _locationInfoRepository.Db.Updateable(dt_LocationInfo) .Where(x => x.LocationCode == dt_LocationInfo.LocationCode) .ExecuteCommand() > 0; if (!res) { return MESresponse($"修改货位失败",false); } return MESresponse($"", true); } /// /// 删除货位 /// /// /// /// public ApiResponse deleteLocation(List locationCode) { WebResponseContent webResponseContent = new WebResponseContent(); int res = _locationInfoRepository.Db.Deleteable().Where(x => locationCode.Contains(x.LocationCode)).ExecuteCommand(); if (res <= 0) { return MESresponse($"删除货位失败",false); } return MESresponse($"", true); } } }