#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命å空间:WIDESEAWCS_TaskInfoService * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * æè¿°ï¼š * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using AutoMapper; using HslCommunication; using HslCommunication.WebSocket; using OfficeOpenXml.FormulaParsing.Excel.Functions.Information; using SqlSugar; using WIDESEAWCS_BasicInfoRepository; using WIDESEAWCS_BasicInfoService; using WIDESEAWCS_Common; using WIDESEAWCS_Core; using WIDESEAWCS_Core.BaseRepository; using WIDESEAWCS_Core.BaseServices; using WIDESEAWCS_Core.Enums; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_DTO.BasicInfo; using WIDESEAWCS_DTO.PlacedBlockDTO; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_IBasicInfoRepository; using WIDESEAWCS_IBasicInfoService; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob.Repository; using static Dm.net.buffer.ByteArrayBuffer; namespace WIDESEAWCS_TaskInfoService { /// <summary> /// 任务æœåŠ¡ç±»ï¼Œæä¾›ä»»åŠ¡ç›¸å…³çš„ä¸šåŠ¡é€»è¾‘æ“作 /// </summary> /// <remarks> /// 主è¦åŠŸèƒ½åŒ…æ‹¬ï¼š <br/> /// 1. 查询门架设备未执行任务 <br/> /// 2. 执行订å•å—æ”¾ç½®æµ‹è¯• <br/> /// 3. 创建和管ç†ä»»åŠ¡ <br/> /// 4. 生æˆå’Œé‡æ–°ç”Ÿæˆä»»åŠ¡ <br/> /// 5. 处ç†å¼‚常任务 <br/> /// 6. 任务完æˆå¤„ç† <br/> /// ä¾èµ–仓储层进行数æ®è®¿é—®ï¼Œé€šè¿‡å·¥ä½œå•元管ç†äº‹åŠ¡ <br/> /// 使用WebSocket进行实时通知,并包å«å®Œæ•´çš„å¼‚å¸¸å¤„ç†æœºåˆ¶ /// </remarks> public class TaskService : ServiceBase<Dt_Task, ITaskRepository>, ITaskService { /// <summary> /// 工作å•å…ƒç®¡ç†æŽ¥å£å®žä¾‹ï¼Œç”¨äºŽç®¡ç†æ•°æ®åº“事务和工作å•å…ƒ /// </summary> private readonly IUnitOfWorkManage _unitOfWorkManage; /// <summary> /// ç”¨äºŽå¯¹è±¡æ˜ å°„çš„æ˜ å°„å™¨å®žä¾‹ /// </summary> private readonly IMapper _mapper; /// <summary> /// 容器仓储接å£å®žä¾‹ï¼Œç”¨äºŽå®¹å™¨ç›¸å…³æ•°æ®æ“作 /// </summary> private readonly IContainerRepository _containerRepository; /// <summary> /// 容器物å“仓储接å£å®žä¾‹ï¼ˆåªè¯»ï¼‰ /// </summary> private readonly IContainerItemRepository _containerItemRepository; /// <summary> /// WebSocketæœåŠ¡å™¨å®žä¾‹ï¼Œç”¨äºŽå¤„ç†WebSocket连接 /// </summary> private readonly WebSocketServer _webSocketServer; /// <summary> /// 订å•详情仓储接å£å®žä¾‹ï¼ˆåªè¯»ï¼‰ /// </summary> private readonly IOrderDetailsRepository _orderDetailsRepository; /// <summary> /// 容器æœåŠ¡æŽ¥å£å®žä¾‹ï¼Œç”¨äºŽç®¡ç†ä¾èµ–注入容器相关æ“作 /// </summary> private readonly IContainerService _containerService; /// <summary> /// è®¢å•æ˜Žç»†æœåŠ¡æŽ¥å£ /// </summary> private readonly IOrderDetailsService _orderDetailsService; /// <summary> /// 订å•行仓储接å£å®žä¾‹ï¼Œç”¨äºŽæ“作订å•è¡Œæ•°æ® /// </summary> private readonly IOrderrowsRepository _orderrowsRepository; /// <summary> /// 订å•容器仓储接å£å®žä¾‹ï¼Œç”¨äºŽæ“作订å•å®¹å™¨ç›¸å…³æ•°æ® /// </summary> private readonly IOrderContainerRepository _orderContainerRepository; public TaskService(ITaskRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IMapper mapper, IContainerRepository containerRepository, IContainerItemRepository containerItemRepository, WebSocketServer webSocketServer, IOrderDetailsRepository orderDetailsRepository, IContainerService containerService, IOrderDetailsService orderDetailsService, IOrderrowsRepository orderrowsRepository, IOrderContainerRepository orderContainerRepository) : base(BaseDal) { _unitOfWorkManage = unitOfWorkManage; _mapper = mapper; _containerRepository = containerRepository; _containerItemRepository = containerItemRepository; _webSocketServer = webSocketServer; _orderDetailsRepository = orderDetailsRepository; _containerService = containerService; _orderDetailsService = orderDetailsService; _orderrowsRepository = orderrowsRepository; _orderContainerRepository = orderContainerRepository; } /// <summary> /// 查询指定门架设备未执行的任务 /// </summary> /// <param name="gantryDeviceNo">门架设备编å·</param> /// <returns>未执行的任务数æ®ï¼Œè‹¥ä¸å˜åœ¨åˆ™è¿”回null</returns> public Dt_Task? QueryAGantryUnExecuteTask(string gantryDeviceNo) { return BaseDal.QueryFirst(x => x.TaskState == (int)TaskStatusEnum.Gantry_New && x.DeviceCode == gantryDeviceNo); } /// <summary> /// 执行订å•å—æ”¾ç½®æµ‹è¯•ï¼Œæ ¹æ®è®¢å•行ID获å–è®¢å•æ˜Žç»†å¹¶è®¡ç®—放置ä½ç½® /// </summary> /// <param name="orderRowId">订å•行ID</param> /// <returns>åŒ…å«æ”¾ç½®å—ä¿¡æ¯çš„Webå“应内容。æˆåŠŸæ—¶è¿”å›žæ”¾ç½®å—列表,失败时返回错误信æ¯</returns> /// <remarks> /// 1. 通过订å•行IDæŸ¥è¯¢è®¢å•æ˜Žç»†æ•°æ® <br/> /// 2. 对æ¯ä¸ªæœ‰æ•ˆè®¢å•明细计算åˆé€‚的放置ä½ç½® <br/> /// 3. 创建容器项和任务记录 <br/> /// 4. 通过WebSocketå‘布放置ä½ç½®ä¿¡æ¯ <br/> /// 5. 返回所有æˆåŠŸæ”¾ç½®çš„å—ä¿¡æ¯ /// </remarks> public WebResponseContent PlaceBlockTest(int orderRowId) { try { List<OrderDetails> orderDetails = _orderDetailsRepository.QueryData(x => x.Orderrowsid == orderRowId); if (orderDetails == null || orderDetails.Count == 0) { return WebResponseContent.Instance.Error("æœªæ‰¾åˆ°è®¢å•æ˜Žç»†ä¿¡æ¯"); } List<PlacedBlock> placedBlocks = new List<PlacedBlock>(); string putPosition = ""; for (int i = 0; i < orderDetails.Count; i++) { try { lock (placedBlocks) { int length = Convert.ToInt32(orderDetails[i].Orderdetails_length); int width = Convert.ToInt32(orderDetails[i].Orderdetails_width); int height = Convert.ToInt32(orderDetails[i].Orderdetails_thickness); OrderInfo orderInfo = _orderDetailsService.GetOrderInfoByBarcode(orderDetails[i].Orderdetails_outid); var (flag, taskPosition, message) = _containerService.GetPosition(orderInfo.OrderHeadId, orderInfo.OrderNo, length, width, height); if (flag && taskPosition != null) { if (string.IsNullOrEmpty(putPosition)) { putPosition = taskPosition.PutPosition; } if (putPosition != taskPosition.PutPosition) { continue; } Dt_OrderContainer orderContainer = _orderContainerRepository.QueryFirst(x => x.OrderNo == orderInfo.OrderNo && x.ContainerCode == taskPosition.PutPosition); Dt_Container putContainer = _containerRepository.QueryFirst(x => x.ContainerCode == taskPosition.PutPosition); if (putContainer == null) { //todo throw new Exception("未找到放货ä½ç½®"); } bool isAdd = false; if (orderContainer == null) { orderContainer = new Dt_OrderContainer() { OrderId = orderInfo.OrderHeadId, ContainerCode = putContainer.ContainerCode, ContainerId = putContainer.Id, OrderNo = orderInfo.OrderNo, }; int containerLength = putContainer.ContainerLength; int containerWidth = putContainer.ContainerWidth; int maxValue = Math.Max(length, width); int minValue = Math.Min(length, width); if (minValue > putContainer.ContainerWidth) { containerLength = maxValue; containerWidth = minValue; } orderContainer.MaxLength = containerLength; orderContainer.MaxWidth = containerWidth; isAdd = true; } if (taskPosition != null) { Dt_ContainerItem dt_ContainerItem = new Dt_ContainerItem() { ContainerId = putContainer.Id, ItemCode = orderInfo.Barcode, ItemLength = length, ItemWidth = width, ItemHeight = height, ItemPositionX = taskPosition.PositionX, ItemPositionY = taskPosition.PositionY, ItemPositionZ = taskPosition.PositionZ, ItemRelaPositionX = taskPosition.PutPositionX, ItemRelaPositionY = taskPosition.PutPositionY, ItemRelaPositionZ = taskPosition.PutPositionZ, ItemStatus = (int)ItemStatusEnum.Assigned, ItemName = orderInfo.Barcode }; Dt_Task dt_Task = new Dt_Task() { PalletCode = orderInfo.Barcode, DeviceCode = putContainer.DeviceCode, TaskState = (int)TaskStatusEnum.Gantry_Wait, TaskType = 0, SourceAddress = "", TargetAddress = $"F06", CurrentAddress = $"F06*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}", NextAddress = $"{putContainer.ContainerCode}*{taskPosition.PutPositionX}*{taskPosition.PutPositionY}*{taskPosition.PutPositionZ}*{taskPosition.PositionR}", ItemInfo = $"{length}*{width}*{height}", Grade = 0, }; putContainer.ContainerStatus = ContainerStatusEnum.NonEmpty.ObjToInt(); _unitOfWorkManage.BeginTran(); BaseDal.AddData(dt_Task); _containerRepository.UpdateData(putContainer); _containerItemRepository.AddData(dt_ContainerItem); if (isAdd) { _orderContainerRepository.AddData(orderContainer); } _unitOfWorkManage.CommitTran(); PlacedBlock placedBlock = new PlacedBlock(new Point3D(taskPosition.PositionX, taskPosition.PositionY, taskPosition.PositionZ), length > width ? length : width, width > length ? length : width, height); placedBlocks.Add(placedBlock); Thread.Sleep(1000); object obj = new { x = taskPosition.PutCenterPositionX - putContainer.ContainerLength / 2, y = taskPosition.PutCenterPositionY - putContainer.ContainerWidth / 2, z = taskPosition.PutPositionZ, length = length > width ? length : width, width = width > length ? length : width, height, }; _webSocketServer.PublishAllClientPayload(obj.Serialize()); } } } } catch (Exception ex) { } } return WebResponseContent.Instance.OK(data: placedBlocks); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } /// <summary> /// åˆ›å»ºä»»åŠ¡å¹¶è®¡ç®—ç‰©å“æ”¾ç½®ä½ç½® /// </summary> /// <param name="takePosition">å–è´§ä½ç½®ç¼–ç </param> /// <param name="putPosition">放货ä½ç½®ç¼–ç </param> /// <param name="deviceCode">设备编ç </param> /// <param name="length">物å“长度</param> /// <param name="width">物å“宽度</param> /// <param name="height">物å“高度</param> /// <returns>åŒ…å«æ“作结果的Webå“应内容</returns> /// <remarks> /// 1. 验è¯å–è´§/放货ä½ç½®æ˜¯å¦å˜åœ¨ <br/> /// 2. 计算物å“在容器ä¸çš„æœ€ä½³æ”¾ç½®ä½ç½® <br/> /// 3. 创建容器物å“记录和任务记录 <br/> /// 4. 通过WebSocket通知客户端 /// </remarks> public WebResponseContent CreateTask(string takePosition, string putPosition, string deviceCode, int length, int width, int height) { try { Dt_Container takeContainer = _containerRepository.QueryFirst(x => x.ContainerCode == takePosition && x.ContainerType == ContainerTypeEnum.TakeContainer.ObjToInt()); if (takeContainer == null) { return WebResponseContent.Instance.Error("å–è´§ä½ç½®ä¸å˜åœ¨"); } List<Dt_Container> containers = _containerRepository.QueryData(x => x.DeviceCode == deviceCode && x.ContainerType == ContainerTypeEnum.PutContainer.ObjToInt()); Dt_Container putContainer = _containerRepository.QueryFirst(x => x.ContainerCode == putPosition && x.ContainerType == ContainerTypeEnum.PutContainer.ObjToInt()); if (putContainer == null) { return WebResponseContent.Instance.Error("放货ä½ç½®ä¸å˜åœ¨"); } int edge = 0; if (putContainer.ContainerNo == containers.Min(x => x.ContainerNo)) { edge = 1; } ContainerSize containerSize = new ContainerSize(putContainer.ContainerLength, putContainer.ContainerWidth, putContainer.ContainerHeight); List<Dt_ContainerItem> containerItems = _containerItemRepository.QueryData(x => x.ContainerId == putContainer.Id); List<PlacedBlock> placedBlocks = containerItems.Select(x => new PlacedBlock(new Point3D(x.ItemPositionX, x.ItemPositionY, x.ItemPositionZ), x.ItemLength > x.ItemLength ? x.ItemLength : x.ItemWidth, x.ItemLength > x.ItemLength ? x.ItemWidth : x.ItemLength, x.ItemHeight)).ToList(); TaskPosition? taskPosition = _containerService.GetTaskPosition(length, width, height, containerSize, placedBlocks, edge); if (taskPosition == null) { return WebResponseContent.Instance.Error("未找到åˆé€‚放置ä½ç½®"); } object obj = new { x = taskPosition.PutCenterPositionX - putContainer.ContainerLength / 2, y = taskPosition.PutCenterPositionY - putContainer.ContainerWidth / 2, z = taskPosition.PutCenterPositionZ, length, width, height, }; _webSocketServer.PublishAllClientPayload(obj.Serialize()); string code = DateTime.Now.ToString("yyyyMMddHHmmss"); Dt_ContainerItem dt_ContainerItem = new Dt_ContainerItem() { ContainerId = putContainer.Id, ItemCode = code, ItemLength = length, ItemWidth = width, ItemHeight = height, ItemPositionX = taskPosition.PositionX, ItemPositionY = taskPosition.PositionY, ItemPositionZ = taskPosition.PositionZ, ItemRelaPositionX = taskPosition.PutPositionX, ItemRelaPositionY = taskPosition.PutPositionY, ItemRelaPositionZ = taskPosition.PutPositionZ, ItemStatus = (int)ItemStatusEnum.Assigned, ItemName = code }; Dt_Task dt_Task = new Dt_Task() { PalletCode = code, DeviceCode = putContainer.DeviceCode, TaskState = (int)TaskStatusEnum.Gantry_New, TaskType = 0, SourceAddress = "", TargetAddress = $"{takeContainer.ContainerNo}", CurrentAddress = $"{takeContainer.ContainerCode}*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}", NextAddress = $"{putContainer.ContainerCode}*{taskPosition.PutPositionX}*{taskPosition.PutPositionY}*{taskPosition.PutPositionZ}*{taskPosition.PositionR}", ItemInfo = $"{length}*{width}*{height}", Grade = 0, }; _containerItemRepository.AddData(dt_ContainerItem); base.AddData(dt_Task); return WebResponseContent.Instance.OK(); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } /// <summary> /// æ ¹æ®è®¢å•ä¿¡æ¯ç”Ÿæˆä»»åŠ¡ /// </summary> /// <param name="orderInfo">订å•ä¿¡æ¯</param> /// <returns>包å«ä¸‰ä¸ªå€¼çš„元组: <br/> /// Item1 - æ“ä½œæ˜¯å¦æˆåŠŸ (bool) <br/> /// Item2 - 生æˆçš„任务对象 (Dt_Task),失败时为null <br/> /// Item3 - é”™è¯¯æ¶ˆæ¯ (string),æˆåŠŸæ—¶ä¸ºç©ºå—符串 /// </returns> /// <remarks> /// 该方法会: <br/> /// 1. æ ¹æ®è®¢å•尺寸获å–åˆé€‚çš„è´§ä½ <br/> /// 2. 创建容器项和任务记录 <br/> /// 3. æ›´æ–°ç›¸å…³å®¹å™¨çŠ¶æ€ <br/> /// 4. åœ¨äº‹åŠ¡ä¸æ‰§è¡Œæ‰€æœ‰æ•°æ®åº“æ“作 /// </remarks> public (bool, Dt_Task?, string) GenerateTask(OrderInfo orderInfo) { try { int length = Convert.ToInt32(orderInfo.Length); int width = Convert.ToInt32(orderInfo.Width); int height = Convert.ToInt32(orderInfo.Thickness); var (flag, taskPosition, message) = _containerService.GetPosition(orderInfo.OrderHeadId, orderInfo.OrderNo, length, width, height); if (flag && taskPosition != null) { Dt_Container putContainer = _containerRepository.QueryFirst(x => x.ContainerCode == taskPosition.PutPosition); if (putContainer == null) { return (false, null, "未找到放货ä½ç½®"); } Dt_Container? takeContainer = GetTakePosition(putContainer.DeviceCode); if (takeContainer == null) { return (false, null, "未找到å–è´§ä½ç½®"); } Dt_OrderContainer orderContainer = _orderContainerRepository.QueryFirst(x => x.OrderNo == orderInfo.OrderNo && x.ContainerCode == putContainer.ContainerCode); bool isAdd = false; bool isUpdate = false; if (orderContainer == null) { orderContainer = new Dt_OrderContainer() { OrderId = orderInfo.OrderHeadId, ContainerCode = putContainer.ContainerCode, ContainerId = putContainer.Id, OrderNo = orderInfo.OrderNo, }; int containerLength = putContainer.ContainerLength; int containerWidth = putContainer.ContainerWidth; int maxValue = Math.Max(length, width); int minValue = Math.Min(length, width); if (minValue > putContainer.ContainerWidth) { containerLength = maxValue; containerWidth = minValue; } orderContainer.MaxLength = containerLength; orderContainer.MaxWidth = containerWidth; isAdd = true; } Dt_ContainerItem dt_ContainerItem = new Dt_ContainerItem() { ContainerId = putContainer.Id, ItemCode = orderInfo.Barcode, ItemLength = length, ItemWidth = width, ItemHeight = height, ItemPositionX = taskPosition.PositionX, ItemPositionY = taskPosition.PositionY, ItemPositionZ = taskPosition.PositionZ, ItemRelaPositionX = taskPosition.PutPositionX, ItemRelaPositionY = taskPosition.PutPositionY, ItemRelaPositionZ = taskPosition.PutPositionZ, ItemStatus = (int)ItemStatusEnum.Assigned, ItemName = orderInfo.Barcode, Remark = $"{takeContainer.ContainerCode}*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}" }; Dt_Task dt_Task = new Dt_Task() { PalletCode = orderInfo.Barcode, DeviceCode = putContainer.DeviceCode, TaskState = (int)TaskStatusEnum.Gantry_Wait, TaskType = 0, SourceAddress = "", TargetAddress = $"{takeContainer.ContainerNo}", CurrentAddress = $"{takeContainer.ContainerCode}*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}", NextAddress = $"{putContainer.ContainerCode}*{taskPosition.PutPositionX}*{taskPosition.PutPositionY}*{taskPosition.PutPositionZ}*{taskPosition.PositionR}", ItemInfo = $"{length}*{width}*{height}", Grade = taskPosition.Edge }; putContainer.ContainerStatus = ContainerStatusEnum.NonEmpty.ObjToInt(); _unitOfWorkManage.BeginTran(); BaseDal.AddData(dt_Task); _containerRepository.UpdateData(putContainer); _containerItemRepository.AddData(dt_ContainerItem); if (isAdd) { _orderContainerRepository.AddData(orderContainer); } else if (isUpdate) { _orderContainerRepository.UpdateData(orderContainer); } _unitOfWorkManage.CommitTran(); return (true, dt_Task, ""); } else { return (false, null, message); } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return (false, null, $"错误,{ex.ExceptionToString()}"); } } /// <summary> /// 釿–°ç”Ÿæˆä»»åŠ¡ /// </summary> /// <param name="task">原始任务对象</param> /// <param name="stationCode">工作站编ç </param> /// <returns> /// 包å«ä¸‰ä¸ªå€¼çš„元组: <br/> /// 1. bool - æ“ä½œæ˜¯å¦æˆåŠŸ <br/> /// 2. Dt_Task - æ›´æ–°åŽçš„任务对象(失败时为null) <br/> /// 3. string - 错误消æ¯ï¼ˆæˆåŠŸæ—¶ä¸ºç©ºå—符串) /// </returns> /// <remarks> /// è¯¥æ–¹æ³•ç”¨äºŽé‡æ–°ç”Ÿæˆä»»åŠ¡ä¿¡æ¯ï¼ŒåŒ…括: <br/> /// 1. è§£æžæ¿åå°ºå¯¸ä¿¡æ¯ <br/> /// 2. 验è¯å–è´§/放货ä½ç½® <br/> /// 3. è®¡ç®—ç‰©å“æ”¾ç½®ä½ç½® <br/> /// 4. 更新任务状æ€å’Œä½ç½®ä¿¡æ¯ <br/> /// 5. åœ¨äº‹åŠ¡ä¸æ›´æ–°æ•°æ®åº“记录 /// </remarks> public (bool, Dt_Task?, string) RegenerateTask(Dt_Task task, string stationCode) { try { int length = 0; int width = 0; int height = 0; Dt_ContainerItem containerItem = _containerItemRepository.QueryFirst(x => x.ItemCode == task.PalletCode); if (containerItem == null) { List<string> itemInfos = task.ItemInfo.Split("*").ToList(); if (itemInfos.Count == 3) { length = Convert.ToInt32(itemInfos[0]); width = Convert.ToInt32(itemInfos[1]); height = Convert.ToInt32(itemInfos[2]); } else { return (false, null, "æ¿å尺寸信æ¯é”™è¯¯"); } } else { length = containerItem.ItemLength; width = containerItem.ItemWidth; height = containerItem.ItemHeight; } string containerCode = task.NextAddress.Split("*")[0]; Dt_Container putContainer = _containerRepository.QueryFirst(x => x.ContainerCode == containerCode); if (putContainer == null) { return (false, null, "未找到放货ä½ç½®"); } Dt_Container? takeContainer = _containerRepository.QueryFirst(x => x.ContainerCode == stationCode); if (takeContainer == null) { return (false, null, "未找到å–è´§ä½ç½®"); } var (flag, taskPosition, message) = _containerService.GetPosition(putContainer, length, width, height); if (!flag || taskPosition == null) { return (false, null, message); } Dt_OrderContainer orderContainer = _orderContainerRepository.QueryFirst(x => x.ContainerCode == putContainer.ContainerCode); bool isAdd = false; if (orderContainer == null) { return (false, null, "未找到订å•与容器绑定关系"); } int containerLength = putContainer.ContainerLength; int containerWidth = putContainer.ContainerWidth; int maxValue = Math.Max(length, width); int minValue = Math.Min(length, width); if (minValue > putContainer.ContainerWidth) { containerLength = maxValue; containerWidth = minValue; } orderContainer.MaxLength = containerLength; orderContainer.MaxWidth = containerWidth; if (containerItem == null) { containerItem = new Dt_ContainerItem() { ContainerId = putContainer.Id, ItemCode = task.PalletCode, ItemLength = length, ItemWidth = width, ItemHeight = height, ItemPositionX = taskPosition.PositionX, ItemPositionY = taskPosition.PositionY, ItemPositionZ = taskPosition.PositionZ, ItemRelaPositionX = taskPosition.PutPositionX, ItemRelaPositionY = taskPosition.PutPositionY, ItemRelaPositionZ = taskPosition.PutPositionZ, ItemStatus = (int)ItemStatusEnum.Assigned, ItemName = task.PalletCode, Remark = $"{takeContainer.ContainerCode}*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}" }; isAdd = true; } else { containerItem.ItemLength = length; containerItem.ItemWidth = width; containerItem.ItemHeight = height; containerItem.ItemPositionX = taskPosition.PositionX; containerItem.ItemPositionY = taskPosition.PositionY; containerItem.ItemPositionZ = taskPosition.PositionZ; containerItem.ItemRelaPositionX = taskPosition.PutPositionX; containerItem.ItemRelaPositionY = taskPosition.PutPositionY; containerItem.ItemRelaPositionZ = taskPosition.PutPositionZ; containerItem.ItemStatus = (int)ItemStatusEnum.Assigned; containerItem.Remark = $"{takeContainer.ContainerCode}*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}"; } task.TaskState = (int)TaskStatusEnum.Gantry_New; task.CurrentAddress = $"{takeContainer.ContainerCode}*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}"; task.NextAddress = $"{putContainer.ContainerCode}*{taskPosition.PutPositionX}*{taskPosition.PutPositionY}*{taskPosition.PutPositionZ}*{taskPosition.PositionR}"; task.ItemInfo = $"{length}*{width}*{height}"; _unitOfWorkManage.BeginTran(); BaseDal.UpdateData(task); _containerRepository.UpdateData(putContainer); _orderContainerRepository.UpdateData(orderContainer); if (isAdd) { _containerItemRepository.AddData(containerItem); } else { _containerItemRepository.UpdateData(containerItem); } _unitOfWorkManage.CommitTran(); return (true, task, ""); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return (false, null, $"错误,{ex.ExceptionToString()}"); } } /// <summary> /// 生æˆå¼‚常任务 /// </summary> /// <param name="orderInfo">订å•ä¿¡æ¯</param> /// <returns>元组包å«ä¸‰ä¸ªå€¼ï¼š <br/> /// Item1 - æ“ä½œæ˜¯å¦æˆåŠŸï¼ˆbool) <br/> /// Item2 - 生æˆçš„任务对象(Dt_Task),失败时为null <br/> /// Item3 - 错误消æ¯ï¼ˆstring),æˆåŠŸæ—¶ä¸ºç©ºå—符串</returns> /// <remarks> /// è¯¥æ–¹æ³•ä¼šæ ¹æ®è®¢å•ä¿¡æ¯ç”Ÿæˆä¸€ä¸ªå¼‚常处ç†ä»»åŠ¡ï¼ŒåŒ…æ‹¬ï¼š <br/> /// 1. 获å–异常ä½ç½® <br/> /// 2. éªŒè¯æ”¾è´§/å–è´§ä½ç½® <br/> /// 3. 创建容器项和任务记录 <br/> /// 4. æäº¤äº‹åŠ¡ /// </remarks> public (bool, Dt_Task?, string) GenerateExceptionTask(OrderInfo orderInfo) { int length = Convert.ToInt32(orderInfo.Length); int width = Convert.ToInt32(orderInfo.Width); int height = Convert.ToInt32(orderInfo.Thickness); var (flag, taskPosition, message) = _containerService.GetExceptionPosition(length, width, height); if (flag && taskPosition != null) { Dt_Container putContainer = _containerRepository.QueryFirst(x => x.ContainerCode == taskPosition.PutPosition); if (putContainer == null) { return (false, null, "未找到放货ä½ç½®"); } Dt_Container? takeContainer = GetTakePosition(putContainer.DeviceCode); if (takeContainer == null) { return (false, null, "未找到å–è´§ä½ç½®"); } Dt_ContainerItem dt_ContainerItem = new Dt_ContainerItem() { ContainerId = putContainer.Id, ItemCode = orderInfo.Barcode, ItemLength = length, ItemWidth = width, ItemHeight = height, ItemPositionX = taskPosition.PositionX, ItemPositionY = taskPosition.PositionY, ItemPositionZ = taskPosition.PositionZ, ItemRelaPositionX = taskPosition.PutPositionX, ItemRelaPositionY = taskPosition.PutPositionY, ItemRelaPositionZ = taskPosition.PutPositionZ, ItemStatus = (int)ItemStatusEnum.Assigned, ItemName = orderInfo.Barcode, Remark = $"{takeContainer.ContainerCode}*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}" }; Dt_Task dt_Task = new Dt_Task() { PalletCode = orderInfo.Barcode, DeviceCode = putContainer.DeviceCode, TaskState = (int)TaskStatusEnum.Gantry_Wait, TaskType = 0, SourceAddress = "", TargetAddress = $"{takeContainer.ContainerNo}", CurrentAddress = $"{takeContainer.ContainerCode}*{taskPosition.TakePositionX}*{taskPosition.TakePositionY}*{taskPosition.TakePositionZ}*{taskPosition.PositionR}", NextAddress = $"{putContainer.ContainerCode}*{taskPosition.PutPositionX}*{taskPosition.PutPositionY}*{taskPosition.PutPositionZ}*{taskPosition.PositionR}", ItemInfo = $"{length}*{width}*{height}", Grade = 0, }; if (taskPosition.TakeCenterPositionZ == 99) { dt_Task.TaskState = (int)TaskStatusEnum.Gantry_BeRelease; } _unitOfWorkManage.BeginTran(); BaseDal.AddData(dt_Task); _containerItemRepository.AddData(dt_ContainerItem); _unitOfWorkManage.CommitTran(); return (true, dt_Task, ""); } else { return (false, null, message); } } /// <summary> /// æ ¹æ®è®¾å¤‡ç¼–å·èŽ·å–å–è´§ä½ç½® /// </summary> /// <param name="deviceCode">设备编å·</param> /// <returns>ç¬¦åˆæ¡ä»¶çš„容器对象,若找ä¸åˆ°åˆ™è¿”回null</returns> /// <remarks> /// 1. 首先查询指定设备下所有å¯ç”¨çš„å–货容器,并按ContainerSortå‡åºæŽ’åº <br/> /// 2. 查找该设备最近的任务记录 <br/> /// 3. å¦‚æžœæ‰¾åˆ°ä»»åŠ¡è®°å½•ï¼Œåˆ™æ ¹æ®ä»»åŠ¡æºåœ°å€åŒ¹é…容器,返回下一个容器(若已是最åŽä¸€ä¸ªåˆ™è¿”回第一个) <br/> /// 4. 如果出现异常或未找到匹é…项,则返回第一个å¯ç”¨å®¹å™¨ /// </remarks> public Dt_Container? GetTakePosition(string deviceCode) { Dictionary<string, OrderByType> orderby = new Dictionary<string, OrderByType>() { { nameof(Dt_Container.ContainerSort), OrderByType.Asc } }; List<Dt_Container> containers = _containerRepository.QueryData(x => x.ContainerType == ContainerTypeEnum.TakeContainer.ObjToInt() && x.DeviceCode == deviceCode && x.ContainerEnable, orderby); try { if (containers == null || containers.Count == 0) { throw new Exception($"未找到对应的å–è´§ä½ç½®,设备编å·:{deviceCode}"); } Dictionary<string, OrderByType> taskOrderby = new Dictionary<string, OrderByType>() { { nameof(Dt_Task.TaskNum), OrderByType.Desc } }; Dt_Task task = BaseDal.QueryFirst(x => x.DeviceCode == deviceCode, taskOrderby); if (task != null) { string? sourceCode = task.SourceAddress.Split("*").FirstOrDefault(); if (!string.IsNullOrEmpty(sourceCode)) { Dt_Container? container = containers.FirstOrDefault(x => x.ContainerCode == sourceCode); if (container != null) { int index = containers.IndexOf(container); if (index + 1 < containers.Count) { return containers[index + 1]; } else { return containers.FirstOrDefault(); } } } } } catch (Exception ex) { } return containers.FirstOrDefault(); } /// <summary> /// 任务完æˆå¤„ç†æ–¹æ³• /// </summary> /// <param name="task">任务实体</param> /// <returns>Webå“应内容</returns> /// <remarks> /// 1. 更新任务状æ€ä¸º"龙门架完æˆ" <br/> /// 2. 更新相关订å•详情状æ€ä¸º"ç åž›æˆåŠŸ" <br/> /// 3. 更新订å•行ä¸çš„æ‰˜ç›˜æ•°é‡ <br/> /// 4. æ ¹æ®ä»»åŠ¡å®Œæˆæƒ…况å‘é€WebSocket通知 <br/> /// 5. 记录æ“作日志并æäº¤äº‹åŠ¡ <br/> /// 6. å¼‚å¸¸æ—¶å›žæ»šäº‹åŠ¡å¹¶è¿”å›žé”™è¯¯ä¿¡æ¯ /// </remarks> public WebResponseContent TaskComplete(Dt_Task task) { try { task.TaskState = TaskStatusEnum.Gantry_Completed.ObjToInt(); _unitOfWorkManage.BeginTran(); OrderDetails orderDetails = _orderDetailsRepository.QueryFirst(x => x.Orderdetails_outid == task.PalletCode); if (orderDetails != null) { orderDetails.Orderdetails_status = PalletingStatusEnmu.PalletingSuccess.ObjToInt(); Orderrows orderrows = _orderrowsRepository.QueryFirst(x => x.id == orderDetails.Orderrowsid); if (orderrows != null) { orderrows.Orderrows_PalletNum = orderrows.Orderrows_PalletNum ?? 0 + 1; Dt_Container container = _containerRepository.QueryFirst(x => task.NextAddress.Contains(x.ContainerCode)); _orderDetailsRepository.UpdateData(orderDetails); _orderrowsRepository.UpdateData(orderrows); if (container.ContainerType == ContainerTypeEnum.ExceptionContainer.ObjToInt()) { int count = Db.Queryable<Dt_ContainerItem>().Count(x => x.ContainerId == container.Id); if (count >= 5) { if (LightStatusStorage.LightStatusDic.ContainsKey(container.ContainerCode)) { LightStatusStorage.LightStatusDic[container.ContainerCode] = LightStatusEnum.LightError; } } } try { List<string> containerItemCodes = _containerItemRepository.QueryData(x => x.ContainerId == container.Id).Select(x => x.ItemCode).ToList(); List<OrderDetails> totalDetails = _orderDetailsRepository.QueryData(x => x.Orderrowsid == orderrows.id); List<OrderDetails> details = totalDetails.Where(x => x.Orderrowsid == orderrows.id && x.Orderdetails_status == PalletingStatusEnmu.PalletingSuccess.ObjToInt() && containerItemCodes.Contains(x.Orderdetails_outid)).ToList(); int sortedNum = totalDetails.Where(x => x.Orderrowsid == orderrows.id && x.Orderdetails_status == PalletingStatusEnmu.PalletingSuccess.ObjToInt()).Count(); List<object> orderData = new List<object>(); foreach (var item in details) { object obj = new { name = item.Orderdetails_name, baseName = item.Orderdetails_productName, size = $"{item.Orderdetails_length}*{item.Orderdetails_width}*{item.Orderdetails_thickness}", process = "", }; orderData.Add(obj); } object data = new { orderCode = orderrows.Orderrows_orderid, orderName = orderrows.Orderrows_name, cusName = orderrows.Orderrows_customer, stationCode = container.ContainerCode, orderTotalNum = totalDetails.Count, sortedNum = sortedNum, unsortedNum = totalDetails.Count - sortedNum, stationSortedNum = details.Count, orderData = orderData, orderId = orderrows.id, release = 0 }; _webSocketServer.PublishAllClientPayload(data.Serialize()); } catch (Exception ex) { } } } BaseDal.DeleteAndMoveIntoHty(task, App.User?.UserId > 0 ? OperateTypeEnum.äººå·¥å®Œæˆ : OperateTypeEnum.自动完æˆ); _unitOfWorkManage.CommitTran(); return WebResponseContent.Instance.OK(); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return WebResponseContent.Instance.Error(ex.Message); } } } }