TaskExtension.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. using ServiceCenter.Extensions;
  2. using ServiceCenter.Logs;
  3. using ServiceCenter.Redis;
  4. using ServiceCenter.SqlSugars;
  5. using SqlSugar;
  6. using WCS.Entity;
  7. using TaskStatus = WCS.Entity.TaskStatus;
  8. namespace WCS.WorkEngineering.Extensions
  9. {
  10. /// <summary>
  11. /// 任务扩展
  12. /// </summary>
  13. public static class TaskExtension
  14. {
  15. /// <summary>
  16. /// 更新任务执行记录
  17. /// 同步更新历史任务
  18. /// </summary>
  19. /// <param name="task">任务信息</param>
  20. /// <param name="db">数据库上下文</param>
  21. /// <param name="curPoint">当前地址</param>
  22. /// <param name="desc">描述</param>
  23. public static void AddWCS_TASK_DTL(this WCS_TaskInfo task, SqlSugarScopeProvider db, string curPoint, string desc) => task.AddWCS_TASK_DTL(db, curPoint, "", desc);
  24. /// <summary>
  25. /// 更新任务执行记录
  26. /// 同步更新历史任务
  27. /// </summary>
  28. /// <param name="task">任务信息</param>
  29. /// <param name="db">数据库上下文</param>
  30. /// <param name="curPoint">当前地址</param>
  31. /// <param name="nextPoint">下一个地址</param>
  32. /// <param name="desc">描述</param>
  33. public static void AddWCS_TASK_DTL(this WCS_TaskInfo task, SqlSugarScopeProvider db, string curPoint, string nextPoint, string desc)
  34. {
  35. db.Insertable(new WCS_TaskDtl
  36. {
  37. ID = Guid.NewGuid(),
  38. ParentTaskCode = task.ID,
  39. CurPoint = curPoint,
  40. NextPoint = nextPoint,
  41. Desc = desc,
  42. AddWho = "WCS"
  43. }).SplitTable().ExecuteCommand();
  44. task.UpdateableOldTask(db);
  45. }
  46. /// <summary>
  47. /// 更新历史表数据
  48. /// </summary>
  49. /// <param name="taskInfo"></param>
  50. /// <param name="db"></param>
  51. public static void UpdateableOldTask(this WCS_TaskInfo taskInfo, SqlSugarScopeProvider db)
  52. {
  53. if (taskInfo.Status == TaskStatus.NewBuild) return;
  54. // 同步任务信息
  55. var taskOld = db.Queryable<WCS_TaskOld>().SplitTable(tabs => tabs.Take(2)).Where(v => v.Id == taskInfo.ID).OrderByDescending(v => v.AddTime).First();
  56. if (taskOld is not null)
  57. {
  58. if (taskInfo.Status >= TaskStatus.Finish) taskInfo.CompleteOrCancelTasks(db);
  59. else
  60. {
  61. taskOld = taskInfo.Mapper<WCS_TaskOld, WCS_TaskInfo>();
  62. taskOld.Id = taskInfo.ID;
  63. db.Updateable(taskOld).Where(x => x.Id == taskOld.Id).SplitTable(x=>x.Take(2)).ExecuteCommand();
  64. }
  65. }
  66. else
  67. {
  68. throw new KnownException($"WCS_TaskOld表中不存在任务:{taskInfo.ID},无法执行WCS_TaskInfo与WCS_TaskOld同步动作", LogLevelEnum.Mid);
  69. }
  70. }
  71. /// <summary>
  72. /// 完成或取消任务
  73. /// </summary>
  74. /// <param name="taskInfo"></param>
  75. /// <param name="db"></param>
  76. public static void CompleteOrCancelTasks(this WCS_TaskInfo taskInfo, SqlSugarScopeProvider db)
  77. {
  78. if (taskInfo.Status is not Entity.TaskStatus.Finish and not Entity.TaskStatus.Cancel) throw new KnownException("任务未完成或取消,无法执行WCS_TaskInfo与WCS_TaskOld同步动作", LogLevelEnum.Mid);
  79. // 任务完成或取消,进行相关同步动作
  80. var taskOld = db.Queryable<WCS_TaskOld>().SplitTable(tabs => tabs.Take(2)).Where(v => v.Id == taskInfo.ID).OrderByDescending(v => v.AddTime).First();
  81. if (taskOld is not null)
  82. {
  83. taskOld = taskInfo.Mapper<WCS_TaskOld, WCS_TaskInfo>();
  84. taskOld.Id = taskInfo.ID;
  85. //更新任务历史表,删除任务当前表
  86. db.Updateable(taskOld).SplitTable(x=>x.Take(2)).ExecuteCommand();
  87. db.Deleteable(taskInfo).ExecuteCommand();
  88. }
  89. else
  90. {
  91. throw new KnownException($"WCS_TaskOld表中不存在任务:{taskInfo.ID},无法执行WCS_TaskInfo与WCS_TaskOld同步动作", LogLevelEnum.Mid);
  92. }
  93. }
  94. /// <summary>
  95. /// 更新表数据
  96. /// </summary>
  97. /// <param name="taskInfo"></param>
  98. /// <param name="db"></param>
  99. public static void Updateable(this WCS_TaskInfo taskInfo, SqlSugarScopeProvider db)
  100. {
  101. taskInfo.EditTime = DateTime.Now;
  102. taskInfo.EditWho = "WCS";
  103. db.Updateable(taskInfo).ExecuteCommand();
  104. }
  105. ///// <summary>
  106. ///// 获取出库任务
  107. ///// </summary>
  108. ///// <param name="taskInfo">任务</param>
  109. ///// <param name="db">db</param>
  110. ///// <param name="allOutCode">可用出库站台</param>
  111. ///// <param name="floor">楼层</param>
  112. ///// <param name="obj">堆垛机</param>
  113. ///// <param name="index">递归次数</param>
  114. ///// <returns></returns>
  115. ///// <exception cref="KnownException"></exception>
  116. //public static WCS_TaskInfo GetOutTask(this WCS_TaskInfo taskInfo, SqlSugarHelper db, List<string> allOutCode, int floor, SRM obj, int index = 1)
  117. //{
  118. // return task;
  119. //}
  120. /// <summary>
  121. /// 获取AGV任务ID
  122. /// </summary>
  123. /// <param name="db">db</param>
  124. /// <returns></returns>
  125. public static int GetAgvTaskId(this SqlSugarHelper db)
  126. {
  127. var id = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(1)).Max(v => v.ID);
  128. return id + 1;
  129. }
  130. /// <summary>
  131. /// 更新任务执行记录
  132. /// </summary>
  133. /// <param name="task">任务信息</param>
  134. public static void UpdateRedisHash(this WCS_TaskInfo task)
  135. {
  136. var key = $"Hash:{task.ID}";
  137. if (task.Status >= TaskStatus.Finish)
  138. {
  139. RedisHub.WMS.Del(key);
  140. }
  141. else
  142. {
  143. RedisHub.WMS.HMSet(key, task.ToDic());
  144. }
  145. }
  146. #region 工字轮支线分流
  147. /// <summary>
  148. /// 初始化码垛信息
  149. /// </summary>
  150. /// <param name="task"></param>
  151. public static void InitStackStructure(this WCS_TaskInfo task, SqlSugarScopeProvider db)
  152. {
  153. var billBomsetinfo = db.Queryable<wms.sqlsugar.model.fj.BillBomsetinfo>().First(x => x.MatCode == task.MatCode);
  154. var billBomsetinfos = db.Queryable<wms.sqlsugar.model.fj.BillBomsetinfo>().Where(x => x.BomSetHdrId == billBomsetinfo.BomSetHdrId).ToList();
  155. var billBomsetgrp = db.Queryable<wms.sqlsugar.model.fj.BillBomsetgrp>().Single(x => x.Id == billBomsetinfo.BomSetHdrId);
  156. //开始构造垛形信息
  157. var palletizing = new WCS_Palletizing()
  158. {
  159. Code = billBomsetgrp.Code,
  160. ShortCode = billBomsetgrp.ShortCode,
  161. ProMaterCode = billBomsetgrp.ProMaterCode,
  162. TpTypeCode = billBomsetgrp.TpTypeCode,
  163. LayerCountQty = 2,
  164. StampType = billBomsetgrp.StampType,
  165. Finish = false,
  166. AddTime = DateTime.Now,
  167. TaskId = task.ID
  168. };
  169. palletizing = db.Insertable(palletizing).ExecuteReturnEntity();
  170. foreach (var item in billBomsetinfos.GroupBy(x => x.Row).OrderBy(x => x.Key))
  171. {
  172. var layerNo = item.Key <= 6 ? 1 : 2;
  173. //获取层信息
  174. var palletizingLayer = db.Queryable<WCS_PalletizingLayer>()
  175. .Single(x => x.PalletizingId == palletizing.Id && x.LayerNo == layerNo);
  176. if (palletizingLayer == null)
  177. {
  178. palletizingLayer = new WCS_PalletizingLayer()
  179. {
  180. LayerNo = layerNo,
  181. PalletizingId = palletizing.Id
  182. };
  183. palletizingLayer = db.Insertable(palletizingLayer).ExecuteReturnEntity();
  184. }
  185. //获取行信息
  186. var palletizingRow = db.Queryable<WCS_PalletizingRow>()
  187. .Single(x => x.PalletizingLayerId == palletizingLayer.Id && x.RowNo == item.Key);
  188. if (palletizingRow == null)
  189. {
  190. palletizingRow = new WCS_PalletizingRow()
  191. {
  192. RowNo = item.Key,
  193. PalletizingLayerId = palletizingLayer.Id
  194. };
  195. palletizingRow = db.Insertable(palletizingRow).ExecuteReturnEntity();
  196. }
  197. //重新查询最新的数据
  198. var layer = palletizingLayer;
  199. palletizingLayer = db.Queryable<WCS_PalletizingLayer>().Single(x => x.Id == layer.Id);
  200. var row = palletizingRow;
  201. palletizingRow = db.Queryable<WCS_PalletizingRow>().Single(x => x.Id == row.Id);
  202. //构造位信息
  203. foreach (var loc in item)
  204. {
  205. var palletizingLoc = db.Queryable<WCS_PalletizingLoc>()
  206. .Single(x => x.PalletizingRowId == palletizingRow.Id && x.XYNo == loc.XYNo);
  207. if (palletizingLoc == null)
  208. {
  209. palletizingLoc = new WCS_PalletizingLoc()
  210. {
  211. IsEmpty = loc.IsEmpty != 0,
  212. XYNo = loc.XYNo,
  213. MatCode = loc.MatCode,
  214. SideNum = loc.SideNum,
  215. SpoolType = loc.SpoolType,
  216. TaskId = task.ID,
  217. PalletizingRowId = palletizingRow.Id,
  218. Finish = false
  219. };
  220. palletizingLoc = db.Insertable(palletizingLoc).ExecuteReturnEntity();
  221. }
  222. //同步是否混合料行
  223. palletizingRow.IsMixRow = loc.IsMixRow != 0;
  224. db.Updateable(palletizingRow).ExecuteCommand();
  225. }
  226. //更新行信息
  227. palletizingRow = db.Queryable<WCS_PalletizingRow>().Includes(x => x.Locs).Single(x => x.Id == row.Id);
  228. palletizingRow.QtyMaxCount = palletizingRow.Locs.Count(x => !x.IsEmpty);
  229. palletizingRow.IsEmpty = palletizingRow.QtyMaxCount <= 0;
  230. palletizingRow.MatCodeList = palletizingRow.Locs.Select(x => x.MatCode).ToList().GetMatList();
  231. db.Updateable(palletizingRow).ExecuteCommand();
  232. //更新层信息
  233. palletizingLayer = db.Queryable<WCS_PalletizingLayer>().Includes(x => x.Rows, l => l.Locs).Single(x => x.Id == layer.Id);
  234. var count = palletizingLayer.Rows.Count(x => !x.IsEmpty); //计算所有不空数量
  235. palletizingLayer.IsEmpty = count <= 0;
  236. palletizingLayer.RowCountQty = palletizingLayer.Rows.Count;
  237. palletizingLayer.Finish = false;
  238. palletizingLayer.MatCodeList = palletizingLayer.Rows.SelectMany(x => x.Locs).Select(x => x.MatCode).ToList().GetMatList();
  239. db.Updateable(palletizingLayer).ExecuteCommand();
  240. }
  241. var palletizing1 = palletizing;
  242. palletizing = db.Queryable<WCS_Palletizing>().Includes(x => x.Layers, r => r.Rows, l => l.Locs).Single(x => x.Id == palletizing1.Id);
  243. //计算垛形信息
  244. var goods = palletizing.Layers.Select(x => x.Rows).SelectMany(x => x).Select(x => x.Locs).SelectMany(x => x).ToList();
  245. palletizing.CountQty = goods.Count(x => !x.IsEmpty);
  246. palletizing.MatCodeList = palletizing.Layers.SelectMany(x => x.Rows).SelectMany(x => x.Locs).Select(x => x.MatCode).ToList().GetMatList();
  247. db.Updateable(palletizing).ExecuteCommand();
  248. }
  249. public static string GetMatList(this List<string> matList)
  250. {
  251. return matList.Distinct().Aggregate("", (current, mat) => current + $"[{mat}]");
  252. }
  253. /// <summary>
  254. /// 去除转义字符
  255. /// </summary>
  256. /// <param name="value"></param>
  257. /// <returns></returns>
  258. public static string RemoveEscapeCharacters(this string? value)
  259. {
  260. return value.Trim('\0', '\a', '\b', '\f', '\n', '\r', '\t', '\v').Trim();
  261. }
  262. #endregion 工字轮支线分流
  263. }
  264. /// <summary>
  265. /// 垛形位信息
  266. /// </summary>
  267. public class StackPosInfo
  268. {
  269. /// <summary>
  270. /// 任务号
  271. /// </summary>
  272. public int TaskNumber { get; set; }
  273. /// <summary>
  274. /// 是否空置
  275. /// </summary>
  276. public bool IsEmpty { get; set; }
  277. /// <summary>
  278. /// 坐标号
  279. /// </summary>
  280. public string XYNo { get; set; }
  281. /// <summary>
  282. /// 物料编码
  283. /// </summary>
  284. public string MatCode { get; set; }
  285. /// <summary>
  286. /// 正反面
  287. /// </summary>
  288. public int SideNum { get; set; }
  289. /// <summary>
  290. /// 工字轮类型
  291. /// </summary>
  292. public string SpoolType { get; set; }
  293. /// <summary>
  294. /// 是否结束
  295. /// </summary>
  296. public bool Finish { get; set; }
  297. }
  298. }