TaskExtension.cs 15 KB

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