TaskRequest_Disp.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. using NX_CommonClassLibrary;
  2. using NX_JsonClassLibrary;
  3. using NX_ModelClassLibrary.BaseModel;
  4. using NX_ModelClassLibrary.Common;
  5. using NX_ModelClassLibrary.CrnModel;
  6. using NX_ModelClassLibrary.CustomEnum;
  7. using NX_ModelClassLibrary.TranModel;
  8. using NX_ModelClassLibrary.WcsDispatch;
  9. using NX_ModelClassLibrary.WmsTask;
  10. using NX_WcsBiz.CommonBusiness;
  11. using NX_WcsDal.WcsDispatch;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Data;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. namespace NX_WcsBiz.WcsDispatch
  19. {
  20. /// <summary>
  21. /// 任务请求调度类
  22. /// </summary>
  23. public class TaskRequest_Disp
  24. {
  25. #region 单例模式
  26. /// <summary>
  27. /// 单例模式对象
  28. /// </summary>
  29. private static TaskRequest_Disp _instance = null;
  30. private static readonly object lockObj = new object();
  31. /// <summary>
  32. /// 单例模式方法
  33. /// </summary>
  34. public static TaskRequest_Disp Instance
  35. {
  36. get
  37. {
  38. if (_instance == null)
  39. {
  40. lock (lockObj)
  41. {
  42. if (_instance == null)
  43. {
  44. _instance = new TaskRequest_Disp();
  45. }
  46. }
  47. }
  48. return _instance;
  49. }
  50. }
  51. #endregion
  52. /// <summary>
  53. /// 任务请求调度入口函数
  54. /// </summary>
  55. /// <param name="taskRequestMd">任务请求传入参数对象</param>
  56. /// <returns></returns>
  57. public DispUntilityReturnMd TaskRequestHandleFunc(TaskRequestMd taskRequestMd)
  58. {
  59. try
  60. {
  61. if (taskRequestMd == null)
  62. {
  63. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"任务请求调度函数传入参数为空!!" };
  64. }
  65. DispUntilityReturnMd retMd;
  66. switch (taskRequestMd.TaskHandleType)
  67. {
  68. case DispatchRequestHandleTypeEnum.托盘申请上线:
  69. retMd = PalletApplyOnLine(taskRequestMd);
  70. break;
  71. case DispatchRequestHandleTypeEnum.自动拆解MWS大任务:
  72. retMd = AutoDisassembleWmsTask();
  73. break;
  74. default:
  75. retMd = new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"未定义任务请求处理枚举,任务请求调度无法识别此类型!!" };
  76. break;
  77. }
  78. return retMd;
  79. }
  80. catch (Exception ex)
  81. {
  82. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"任务请求调度函数发生异常:【{ex.Message}】。" };
  83. }
  84. }
  85. private DispUntilityReturnMd PalletApplyOnLine(TaskRequestMd taskRequestMd)
  86. {
  87. BasWcsLocMd taskRequestLoc = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocCode == taskRequestMd.CurrentLocNo && (x.LocTypeCode == "OnLineLoc" || x.LocTypeCode == "OnLineAndGeneralLoc"));
  88. if (taskRequestLoc == null)
  89. {
  90. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"托盘上线处理的请求参数验证错误,传入站台不是系统配置好的站台号,不允许上线!{GetRetMsg(taskRequestMd)}" };
  91. }
  92. WmsTskTaskMd wmsTskTaskMd = TaskRequest_Dal.Instance.GetUnfinishWmsTaskOfPalletCode(taskRequestMd.PalletCode);
  93. if (wmsTskTaskMd != null)
  94. {
  95. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"托盘上线处理的请求参数验证错误,传入托盘号已经存在未完成的WMS大任务数据,不允许再次上线!{GetRetMsg(taskRequestMd)}" };
  96. }
  97. WcsCrnCmdMd wcsCrnCmdMd = TaskRequest_Dal.Instance.GetUnfinishWcsCrnCmdOfPalletCode(taskRequestMd.PalletCode);
  98. if (wcsCrnCmdMd != null)
  99. {
  100. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"托盘上线处理的请求参数验证错误,传入托盘号已经存在未完成的堆垛机指令数据,不允许再次上线!{GetRetMsg(taskRequestMd)}" };
  101. }
  102. WcsTranCmdMd wcsTranCmdMd = TaskRequest_Dal.Instance.GetUnfinishWcsTranCmdOfPalletCode(taskRequestMd.PalletCode);
  103. if (wcsTranCmdMd != null)
  104. {
  105. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"托盘上线处理的请求参数验证错误,传入托盘号已经存在未完成的输送线指令数据,不允许再次上线!{GetRetMsg(taskRequestMd)}" };
  106. }
  107. string trayCode = string.Empty;
  108. if (!TaskRequest_Dal.Instance.VerifyTrayMsgAndBalanceMsg(taskRequestMd.PalletCode, out trayCode))
  109. {
  110. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"托盘上线处理的请求参数验证错误,校验传入托盘号的库存和组盘信息错误,不允许上线!{GetRetMsg(taskRequestMd)}" };
  111. }
  112. //目前只有一个库区,后续增加多库区分配和负载均衡配置 TODO:孙亚龙
  113. BasWcsLocMd eLocNo = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocTypeCode == "RegionLoc");
  114. BasNextLocRouteMd basNextLocRouteMd = TaskRequest_Dal.Instance.GetRouteMsg(taskRequestLoc, eLocNo);
  115. if (basNextLocRouteMd == null)
  116. {
  117. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"托盘上线处理的请求参数验证错误,获取起点:【{taskRequestLoc.LocCode}】到终点:【{eLocNo.LocCode}】的路线信息发生错误,不允许上线!{GetRetMsg(taskRequestMd)}" };
  118. }
  119. BasRegionMd regionMd = TaskRequest_Dal.Instance.GetRegionMd(eLocNo.RegionCode);
  120. //生成WMS大任务信息。
  121. int row = TaskRequest_Dal.Instance.InsertWmsTaskData(taskRequestMd, eLocNo, trayCode, basNextLocRouteMd, regionMd);
  122. if (row > 0)
  123. {
  124. return new DispUntilityReturnMd { IsSuccess = true, RetMsg = "托盘上线处理成功!" };
  125. }
  126. else
  127. {
  128. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = "托盘上线处理失败!生成WMS大任务数据错误!!" };
  129. }
  130. }
  131. private DispUntilityReturnMd AutoDisassembleWmsTask()
  132. {
  133. try
  134. {
  135. WmsTskTaskMd wmsTskTaskMd = TaskRequest_Dal.Instance.GetWmsTaskOriginalState(AppConfigHelper.Get("CurrWcsControlRegionCode"));
  136. if (wmsTskTaskMd != null)
  137. {
  138. BasWcsLocMd sLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocCode == wmsTskTaskMd.SlocCode);
  139. BasWcsLocMd eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocCode == wmsTskTaskMd.ElocCode);
  140. if (sLocMd.LocCode == eLocMd.LocCode && sLocMd.LocTypeCode == "RegionLoc" && eLocMd.LocTypeCode == "RegionLoc" && wmsTskTaskMd.TaskType == WmsTaskTypeEnum.内伸货位移库任务)
  141. {
  142. BasBinMd sBinMd = TaskRequest_Dal.Instance.GetBinMdOfCode(wmsTskTaskMd.SbinCode);
  143. BasBinMd eBin = TaskRequest_Dal.Instance.GetBinMdOfCode(wmsTskTaskMd.EbinCode);
  144. BasWcsDevMd DevMd = TaskRequest_Dal.Instance.GetCrnDevMsg(sBinMd.ShelfCode);
  145. WmsTskTaskMd retWmsTaskMd = TaskRequest_Dal.Instance.InsertCrnCmdAndUpdateWmsTask(wmsTskTaskMd, sBinMd, eBin, DevMd);
  146. if (retWmsTaskMd != null)
  147. {
  148. return new DispUntilityReturnMd { IsSuccess = true, RetMsg = $"WMS大任务拆解为堆垛机指令成功。【{JsonHelper.ToJson(retWmsTaskMd)}】" };
  149. }
  150. else
  151. {
  152. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"WMS大任务拆解为堆垛机指令失败。【{JsonHelper.ToJson(wmsTskTaskMd)}】" };
  153. }
  154. }
  155. BasNextLocRouteMd basNextLocRouteMd = TaskRequest_Dal.Instance.GetRouteMsg(sLocMd, eLocMd);
  156. BasWcsDevMd devMd = BasCommon_Biz.Instance.basWcsDevMdList.FirstOrDefault(x => x.DevCode == basNextLocRouteMd.DevNo);
  157. eLocMd = BasCommon_Biz.Instance.allWcsLocList.FirstOrDefault(x => x.LocCode == basNextLocRouteMd.NextLocNo);
  158. if (basNextLocRouteMd == null)
  159. {
  160. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"WMS大任务验证错误,无法进行拆解。获取起点:【{sLocMd.LocCode}】到终点:【{eLocMd.LocCode}】的路线信息发生错误!【{JsonHelper.ToJson(wmsTskTaskMd)}】" };
  161. }
  162. //拆解为输送线指令
  163. if (devMd.DevTypeCode == "TranType")
  164. {
  165. //ToDo: 增加正在作业任务数量的限制,获取参数表入库作业的最大任务数量。
  166. int WmsInstockTaskLimitNum = TaskRequest_Dal.Instance.GetLimitWmsTaskNum("InStockTaskMaxNum");
  167. int runingWmsInstockTaskNum = TaskRequest_Dal.Instance.GetRuningWmsInstockTaskNum();
  168. if (runingWmsInstockTaskNum >= WmsInstockTaskLimitNum)
  169. {
  170. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"WMS正在作业的入库大任务数量已经超过入库最大的限制任务数量,请等待前面的入库任务做完。【{JsonHelper.ToJson(wmsTskTaskMd)}】" };
  171. }
  172. WmsTskTaskMd retWmsTaskMd = TaskRequest_Dal.Instance.InsertTranCmdAndUpdateWmsTask(wmsTskTaskMd,sLocMd,eLocMd, basNextLocRouteMd);
  173. if (retWmsTaskMd != null)
  174. {
  175. return new DispUntilityReturnMd { IsSuccess = true, RetMsg = $"WMS大任务拆解为输送线指令成功。【{JsonHelper.ToJson(retWmsTaskMd)}】" };
  176. }
  177. else
  178. {
  179. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"WMS大任务拆解为输送线指令失败。【{JsonHelper.ToJson(wmsTskTaskMd)}】" };
  180. }
  181. }
  182. //拆解为堆垛机指令
  183. if (devMd.DevTypeCode == "CrnType")
  184. {
  185. //ToDo: 增加正在作业任务数量的限制,获取参数表入库作业的最大任务数量。
  186. int WmsOutstockTaskLimitNum = TaskRequest_Dal.Instance.GetLimitWmsTaskNum("OutStockTaskMaxNum");
  187. int runingWmsOutstockTaskNum = TaskRequest_Dal.Instance.GetRuningWmsOutstockTaskNum();
  188. if (runingWmsOutstockTaskNum >= WmsOutstockTaskLimitNum)
  189. {
  190. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"WMS正在作业的出库大任务数量已经超过出库最大的限制任务数量,请等待前面的出库任务做完。【{JsonHelper.ToJson(wmsTskTaskMd)}】" };
  191. }
  192. BasBinMd sBin = TaskRequest_Dal.Instance.GetBinMdOfCode(wmsTskTaskMd.SbinCode);
  193. BasBinMd eBin = TaskRequest_Dal.Instance.GetBinMdOfCode(wmsTskTaskMd.EbinCode);
  194. WmsTskTaskMd retWmsTaskMd = TaskRequest_Dal.Instance.InsertCrnCmdAndUpdateWmsTask(wmsTskTaskMd, sBin, eBin, basNextLocRouteMd);
  195. if (retWmsTaskMd != null)
  196. {
  197. return new DispUntilityReturnMd { IsSuccess = true, RetMsg = $"WMS大任务拆解为堆垛机指令成功。【{JsonHelper.ToJson(retWmsTaskMd)}】" };
  198. }
  199. else
  200. {
  201. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"WMS大任务拆解为堆垛机指令失败。【{JsonHelper.ToJson(wmsTskTaskMd)}】" };
  202. }
  203. }
  204. }
  205. return null;
  206. }
  207. catch (Exception ex)
  208. {
  209. return new DispUntilityReturnMd { IsSuccess = false, RetMsg = $"自动拆解WMS大任务函数发生异常:【{ex.Message}】。" };
  210. }
  211. }
  212. private string GetRetMsg(TaskRequestMd taskRequestMd)
  213. {
  214. return $"请求参数 --- 托盘号:【{taskRequestMd.PalletCode}】,请求站台号:【{taskRequestMd.CurrentLocNo}】,请求处理类型:【{taskRequestMd.TaskHandleType}】";
  215. }
  216. }
  217. }