WCSApi.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. using DBHelper;
  2. using Microsoft.AspNetCore.Mvc;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using WCS.Core;
  7. using WCS.Entity;
  8. using WCS.Entity.Protocol;
  9. using WCS.Service.Entity;
  10. using WCS.Service.Extensions;
  11. namespace WCS.Service.WebApi
  12. {
  13. [ApiController]
  14. [Route("[controller]/[action]")]
  15. public class WCSApi : ControllerBase
  16. {
  17. [HttpPost]
  18. public WcsContractApiResponse I_WMS_CreateTasks(List<PushCreateWcsTaskRequest> list)
  19. {
  20. var res = new WcsContractApiResponse();
  21. try
  22. {
  23. DB.Do(db =>
  24. {
  25. foreach (var obj in list)
  26. {
  27. if (obj.TaskType == "3")//移库任务
  28. {
  29. var wmstaskid = int.Parse(obj.WMSTaskNo);
  30. if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmstaskid))
  31. throw new Exception("任务号" + wmstaskid + "重复下发");
  32. var scid = int.Parse(obj.SRMNo.Last().ToString());
  33. var tunnel = (scid > 3 ? "TM" : "TY") + obj.StartTunnel;
  34. var task = new WCS_TASK
  35. {
  36. TYPE = TaskType.移库,
  37. STATUS = WCS.Entity.TaskStatus.新建,
  38. DEVICE = "SRM" + obj.SRMNo.Last(),
  39. BARCODE = obj.PalletCode,
  40. ADDRFROM = obj.StartLocation,
  41. ADDRTO = obj.EndLocation,
  42. UPDATETIME = DateTime.Now,
  43. UPDATEUSER = "WMS",
  44. TUNNEL = tunnel,
  45. WMSTASK = int.Parse(obj.WMSTaskNo),
  46. TaskGroupKey = obj.TaskGroupKey
  47. };
  48. db.Default.Add(task);
  49. db.Default.SaveChanges();
  50. //task.CreateStatusLog(db);
  51. }
  52. else if (obj.TaskType == "2")
  53. { //出库任务
  54. var wmstaskid = int.Parse(obj.WMSTaskNo);
  55. if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmstaskid))
  56. throw new Exception("任务号" + wmstaskid + "重复下发");
  57. var tunnel = "TY" + obj.SRMNo.Last();
  58. var task = new WCS_TASK
  59. {
  60. TYPE = TaskType.出库,
  61. STATUS = WCS.Entity.TaskStatus.新建,
  62. DEVICE = "SC" + obj.SRMNo.Last(),
  63. BARCODE = obj.PalletCode,
  64. ADDRFROM = string.Format("{0}-{1}-{2}", obj.StartRow, obj.StartCol, obj.StartLayer),
  65. ADDRTO = obj.EndLocation,
  66. UPDATETIME = DateTime.Now,
  67. UPDATEUSER = "WMS",
  68. TUNNEL = tunnel,
  69. WMSTASK = int.Parse(obj.WMSTaskNo),
  70. ADDRNEXT = obj.EndLocation
  71. };
  72. //当前货物可以使用的放货点
  73. var deliveryPoints = Device.Find(task.DEVICE).Create<SRMDevice>().GetDeliveryPoint();
  74. //确定放货站台 通过设备组关联 此时一定是一组设备组
  75. //结果为堆垛机放货设备组
  76. var group = Device.Where(v => v.ROUTES.Any(p => p.NEXT.CODE == task.ADDRTO)).SelectMany(v => v.DEVICEGROUP).Select(v => v.MEMBER);
  77. //结果为当前堆垛机可用设备 此时会是两个单独的设备
  78. deliveryPoints = deliveryPoints.Where(v => group.Contains(v.Entity)).OrderByDescending(v => v.Entity.CODE).ToList();
  79. //判断是否可以到达
  80. //确定当前工位的货物是一工位还是二工位
  81. if (obj.StartCol.ToShort().OddNumberOrEven())
  82. {
  83. //一工位 也是设备在堆垛机放货后的第一个地点
  84. task.SRMSTATION = deliveryPoints[0].Entity.CODE;
  85. var g = Device.Find(task.ADDRTO).Create<StationDeviceGroup>().Items.ToArray();
  86. if (deliveryPoints[0].Entity.PATHS.Any(v => v.END == g[0].Entity)) task.ADDRTO = g[0].Entity.CODE;
  87. else task.ADDRTO = g[1].Entity.CODE;
  88. }
  89. else
  90. {
  91. //二工位
  92. task.SRMSTATION = deliveryPoints[1].Entity.CODE;
  93. var g = Device.Find(task.ADDRTO).Create<StationDeviceGroup>().Items.ToArray();
  94. if (deliveryPoints[1].Entity.PATHS.Any(v => v.END == g[0].Entity)) task.ADDRTO = g[0].Entity.CODE;
  95. else task.ADDRTO = g[1].Entity.CODE;
  96. }
  97. db.Default.Add(task);
  98. db.Default.SaveChanges();
  99. //task.CreateStatusLog(db);
  100. }
  101. else if (obj.TaskType == "1")
  102. {//入库任务
  103. var wmstaskid = int.Parse(obj.WMSTaskNo);
  104. if (db.Default.Set<WCS_TASK>().Any(v => v.WMSTASK == wmstaskid))
  105. throw new Exception("任务号" + wmstaskid + "重复下发");
  106. if (obj.StartLocation.Contains("_Back_"))
  107. {//生成AGV入库任务
  108. var ws = int.Parse(obj.StartLocation.Split('_')[1]);
  109. var agvtask = new WCS_AGVTask
  110. {
  111. AGVStatus = AGVTaskStatus.新建,
  112. Status = AGVTaskStatus.新建,
  113. Position = obj.StartLocation,
  114. TaskType = AGVTaskType.入库,
  115. CreateTime = DateTime.Now,
  116. UpdateTime = DateTime.Now,
  117. Workshop = ws,
  118. };
  119. if (ws == 13 || ws == 14)
  120. {
  121. agvtask.Station = "2088";
  122. agvtask.Workshop = 1314;
  123. }
  124. else if (ws == 1)
  125. {
  126. agvtask.Station = "2122";
  127. }
  128. else if (ws == 2)
  129. agvtask.Station = "2131";
  130. else if (ws == 3)
  131. agvtask.Station = "2143";
  132. db.Default.Set<WCS_AGVTask>().Add(agvtask);
  133. db.Default.SaveChanges();
  134. }
  135. else
  136. {
  137. var task = new WCS_TASK
  138. {
  139. TYPE = TaskType.入库,
  140. STATUS = WCS.Entity.TaskStatus.新建,
  141. BARCODE = obj.PalletCode,
  142. ADDRFROM = obj.StartLocation,
  143. ADDRTO = obj.EndLocation,
  144. UPDATETIME = DateTime.Now,
  145. UPDATEUSER = "WMS",
  146. WMSTASK = int.Parse(obj.WMSTaskNo)
  147. };
  148. db.Default.Add(task);
  149. db.Default.SaveChanges();
  150. //task.CreateStatusLog(db);
  151. }
  152. }
  153. }
  154. });
  155. res.ResType = true;
  156. }
  157. catch (Exception ex)
  158. {
  159. res.ResMessage = ex.GetBaseException().Message;
  160. }
  161. return res;
  162. }
  163. [HttpPost]
  164. public WcsContractApiResponse I_WMS_CreateAGVTask(PushCreateAGVTaskRequest obj)
  165. {
  166. var res = new WcsContractApiResponse();
  167. try
  168. {
  169. DB.Do(db =>
  170. {
  171. if (obj.Type == 1)
  172. {
  173. var ws = int.Parse(obj.StartPos.Split('_')[1]);
  174. var agvtask = new WCS_AGVTask
  175. {
  176. AGVStatus = AGVTaskStatus.新建,
  177. Status = AGVTaskStatus.新建,
  178. Position = obj.StartPos,
  179. TaskType = AGVTaskType.入库,
  180. CreateTime = DateTime.Now,
  181. UpdateTime = DateTime.Now,
  182. Workshop = ws,
  183. };
  184. if (ws == 13 || ws == 14)
  185. {
  186. agvtask.Station = "2088";
  187. agvtask.Workshop = 1314;
  188. }
  189. else if (ws == 1)
  190. {
  191. agvtask.Station = "2122";
  192. }
  193. else if (ws == 2)
  194. agvtask.Station = "2131";
  195. else if (ws == 3)
  196. agvtask.Station = "2143";
  197. db.Default.Set<WCS_AGVTask>().Add(agvtask);
  198. db.Default.SaveChanges();
  199. }
  200. else
  201. throw new Exception($"类型{obj.Type}不支持");
  202. });
  203. res.ResType = true;
  204. }
  205. catch (Exception ex)
  206. {
  207. res.ResMessage = ex.GetBaseException().Message;
  208. }
  209. return res;
  210. }
  211. [HttpPost]
  212. public WcsContractApiResponse I_CancelWCSTaskByCode(string code)
  213. {
  214. var res = new WcsContractApiResponse();
  215. try
  216. {
  217. DB.Do(db =>
  218. {
  219. var task = db.Default.Set<WCS_TASK>().Where(v => v.BARCODE == code && v.STATUS < WCS.Entity.TaskStatus.已完成 && v.TYPE == TaskType.组盘).FirstOrDefault();
  220. if (task == null)
  221. throw new Exception("WCS任务不存在");
  222. task.STATUS = WCS.Entity.TaskStatus.已取消;
  223. task.UPDATETIME = DateTime.Now;
  224. task.UPDATEUSER = "RF";
  225. db.Default.SaveChanges();
  226. });
  227. res.ResType = true;
  228. }
  229. catch (Exception ex)
  230. {
  231. res.ResMessage = ex.GetBaseException().Message;
  232. }
  233. return res;
  234. }
  235. [HttpPost]
  236. public WcsContractApiResponse I_CancelWCSTaskByID(int wmstaskId)
  237. {
  238. var res = new WcsContractApiResponse();
  239. try
  240. {
  241. DB.Do(db =>
  242. {
  243. var task = db.Default.Set<WCS_TASK>().Where(v => v.WMSTASK == wmstaskId).FirstOrDefault();
  244. if (task == null)
  245. throw new Exception("WCS任务不存在");
  246. if (task.STATUS != WCS.Entity.TaskStatus.新建)
  247. throw new Exception("WCS任务当前状态不允许取消");
  248. task.STATUS = WCS.Entity.TaskStatus.已取消;
  249. task.UPDATETIME = DateTime.Now;
  250. task.UPDATEUSER = "WMS";
  251. db.Default.SaveChanges();
  252. if (task.TYPE == TaskType.出库 && task.AgvTask > 0)
  253. {
  254. var agvtask = db.Default.Set<WCS_AGVTask>().Find(task.AgvTask);
  255. agvtask.Status = AGVTaskStatus.取消;
  256. agvtask.UpdateTime = DateTime.Now;
  257. db.Default.SaveChanges();
  258. }
  259. });
  260. res.ResType = true;
  261. }
  262. catch (Exception ex)
  263. {
  264. res.ResMessage = ex.GetBaseException().Message;
  265. }
  266. return res;
  267. }
  268. ///// <summary>
  269. ///// WMS 通过该接口获取码垛位当前各位置对应的托盘码
  270. ///// </summary>
  271. ///// <returns></returns>
  272. //[HttpGet]
  273. //public List<KeyValueViewModel<string, string>> I_WMS_GetPalletCode()
  274. //{
  275. // //找出所有组盘站台信息
  276. // var station = Device.Where(v => v.Is(DF.组盘)).ToList();
  277. // //找出所有有光电信号站台中的任务号
  278. // var taskNumbers = station.Select(v => v.Device<IStation521>())
  279. // .Where(p => p.Data.G_TaskId != 0 && p.Data.G_PhStatus)
  280. // .Select(p => p.Data.G_TaskId);
  281. // var result = new List<KeyValueViewModel<string, string>>();
  282. // DB.Do(db =>
  283. // {
  284. // //找到有光电的位置对应的任务
  285. // var tasks = db.Default.Set<WCS_TASK>().AsNoTracking().Where(task => taskNumbers.Any(x => task.ID == x)).ToList();
  286. // station.ForEach(p =>
  287. // {
  288. // var value = tasks.FirstOrDefault(task => task.ADDRTO == p.CODE);
  289. // result.Add(new KeyValueViewModel<string, string>()
  290. // {
  291. // Key = p.CODE,
  292. // Value = value == null ? null : value.BARCODE,
  293. // });
  294. // });
  295. // });
  296. // return result;
  297. //}
  298. ///// <summary>
  299. ///// 通过该接口获取指定条件设备信息
  300. ///// </summary>
  301. ///// <param name="model">筛选条件</param>
  302. ///// <returns></returns>
  303. //[HttpGet]
  304. //public List<DeviceStatusViewModel> GetDeviceStatus([FromQuery] DeviceStatusViewModel model)
  305. //{
  306. // var result = new List<DeviceStatusViewModel>();
  307. // //找到所有设备的读取协议
  308. // var rgv = Device.Where(v => v.IsRGV()).Select(v => v.Device<IRGV521>());
  309. // //var sc = Device.Where(v => v.IsSC()).Select(v => v.Device<ISC521>());
  310. // var conv = Device.Where(v => v.IsConv()).Select(v => v.Device<IStation521>());
  311. // //var robot = Device.Where(v => v.IsRobot()).Select(v => v.Device<IRobot>());
  312. // #region 检索分两部分,设备、任务(数据库)
  313. // #region 设备信息
  314. // if (!string.IsNullOrEmpty(model.CODE))
  315. // {
  316. // result.AddRange(GetDeviceStatusWhere(rgv, v => v.Entity.CODE == model.CODE));
  317. // //result.AddRange(GetDeviceStatusWhere(sc, v => v.Entity.CODE == model.CODE));
  318. // result.AddRange(GetDeviceStatusWhere(conv, v => v.Entity.CODE == model.CODE));
  319. // //result.AddRange(GetDeviceStatusWhere(robot, v => v.Entity.CODE == model.CODE));
  320. // }
  321. // if (model.TASKNUM > 10000)
  322. // {
  323. // result.AddRange(GetDeviceStatusWhere(rgv, v => v.Data.TaskID_1 == model.TASKNUM));
  324. // //result.AddRange(GetDeviceStatusWhere(sc, v => v.Data.TaskID == model.TASKNUM));
  325. // result.AddRange(GetDeviceStatusWhere(conv, v => v.Data.G_TaskId == model.TASKNUM));
  326. // //result.AddRange(GetDeviceStatusWhere(robot, v => v.Data.TaskID == model.TASKNUM));
  327. // }
  328. // if (model.REQUEST != null)
  329. // {
  330. // result.AddRange(GetDeviceStatusWhere(conv, v => v.Data.G_Request == model.REQUEST));
  331. // }
  332. // if (model.PH_STATUS != null)
  333. // {
  334. // result.AddRange(GetDeviceStatusWhere(rgv, v => v.Data.TaskID_1 == model.TASKNUM));
  335. // result.AddRange(GetDeviceStatusWhere(conv, v => v.Data.G_Request == model.REQUEST));
  336. // }
  337. // if (!string.IsNullOrEmpty(model.ADDRFROM))
  338. // {
  339. // result.AddRange(GetDeviceStatusWhere(rgv, v => v.Data.StartPosition_1 == short.Parse(model.ADDRFROM)));
  340. // //result.AddRange(GetDeviceStatusWhere(sc, v => model.ADDRFROM.Contains(v.Data.SLine.ToString())
  341. // // || model.ADDRFROM.Contains(v.Data.SCol.ToString())
  342. // // || model.ADDRFROM.Contains(v.Data.SLayer.ToString())));
  343. // }
  344. // if (!string.IsNullOrEmpty(model.ADDRTO))
  345. // {
  346. // result.AddRange(GetDeviceStatusWhere(rgv, v => v.Data.DestPosition_1 == short.Parse(model.ADDRTO)));
  347. // //result.AddRange(GetDeviceStatusWhere(sc, v => model.ADDRTO.Contains(v.Data.ELine.ToString())
  348. // // || model.ADDRTO.Contains(v.Data.ECol.ToString())
  349. // // || model.ADDRTO.Contains(v.Data.ELayer.ToString())));
  350. // result.AddRange(GetDeviceStatusWhere(conv, v => v.Data.G_GoodsEnd == short.Parse(model.ADDRTO)));
  351. // //result.AddRange(GetDeviceStatusWhere(robot, v => v.Data.Target == short.Parse(model.ADDRTO)));
  352. // }
  353. // #endregion 设备信息
  354. // #region 任务信息
  355. // //获取所有设备上的任务信息
  356. // if (model.TYPE != null || !string.IsNullOrEmpty(model.BARCODE))
  357. // {
  358. // var info = new List<DeviceStatusViewModel>();
  359. // var ids = result.Select(v => v.TASKNUM);
  360. // info.AddRange(GetDeviceStatusWhere(rgv, v => v.Data.TaskID_1 > 10000));
  361. // //info.AddRange(GetDeviceStatusWhere(sc, v => v.Data.TaskID > 10000));
  362. // info.AddRange(GetDeviceStatusWhere(conv, v => v.Data.G_TaskId > 10000));
  363. // //info.AddRange(GetDeviceStatusWhere(robot, v => v.Data.TaskID > 10000));
  364. // result.AddRange(info.Where(v => !ids.Any(b => b == v.TASKNUM)));
  365. // }
  366. // DB.Do(db =>
  367. // {
  368. // var ids = result.Select(v => v.TASKNUM);
  369. // var tasks = db.Default.Set<WCS_TASK>().AsNoTracking().Where(v => ids.Any(b => b == v.ID)).ToList();
  370. // tasks.ForEach(task =>
  371. // {
  372. // var info = result.Find(v => v.TASKNUM == task.ID);
  373. // info.TYPE = task.TYPE;
  374. // info.BARCODE = task.BARCODE;
  375. // });
  376. // });
  377. // if (model.TYPE != null)
  378. // {
  379. // result = result.Where(v => v.TYPE == model.TYPE).ToList();
  380. // }
  381. // if (!string.IsNullOrEmpty(model.BARCODE))
  382. // {
  383. // result = result.Where(v => v.BARCODE != null && v.BARCODE.Contains(model.BARCODE)).ToList();
  384. // }
  385. // #endregion 任务信息
  386. // #endregion 检索分两部分,设备、任务(数据库)
  387. // return result;
  388. //}
  389. #region 静态方法
  390. ///// <summary>
  391. ///// 获取RGV设备信息
  392. ///// </summary>
  393. ///// <param name="soue"></param>
  394. ///// <param name="func"></param>
  395. ///// <returns></returns>
  396. //public static List<DeviceStatusViewModel> GetDeviceStatusWhere(IEnumerable<Device<IRGV521>> soue, Func<Device<IRGV521>, bool> func)
  397. //{
  398. // var result = new List<DeviceStatusViewModel>();
  399. // result.AddRange(soue.Where(func).Select(device =>
  400. // {
  401. // return new DeviceStatusViewModel
  402. // {
  403. // CODE = device.Entity.CODE,
  404. // TASKNUM = device.Data.TaskID_1,
  405. // PH_STATUS = device.Data.PH_Status_1,
  406. // ADDRFROM = device.Data.StartPosition_1.ToString(),
  407. // ADDRTO = device.Data.DestPosition_1.ToString(),
  408. // };
  409. // }));
  410. // return result;
  411. //}
  412. ///// <summary>
  413. ///// 获取堆垛机设备信息
  414. ///// </summary>
  415. ///// <param name="soue"></param>
  416. ///// <param name="func"></param>
  417. ///// <returns></returns>
  418. //public static List<DeviceStatusViewModel> GetDeviceStatusWhere(IEnumerable<Device<ISC521>> soue, Func<Device<ISC521>, bool> func)
  419. //{
  420. // var result = new List<DeviceStatusViewModel>();
  421. // result.AddRange(soue.Where(func).Select(device =>
  422. // {
  423. // var info = new DeviceStatusViewModel
  424. // {
  425. // CODE = device.Entity.CODE,
  426. // TASKNUM = device.Data.TaskID,
  427. // ADDRFROM = $"{device.Data.SLine}-{device.Data.SCol}-{device.Data.SLayer}",
  428. // ADDRTO = device.Data.ELine.ToString(),
  429. // };
  430. // if (device.Data.ECol != 0 && device.Data.ELayer != 0)
  431. // info.ADDRTO = $"{device.Data.ELine}-{device.Data.ECol}-{device.Data.ELayer}";
  432. // return info;
  433. // }));
  434. // return result;
  435. //}
  436. ///// <summary>
  437. ///// 获取输送机设备信息
  438. ///// </summary>
  439. ///// <param name="soue"></param>
  440. ///// <param name="func"></param>
  441. ///// <returns></returns>
  442. //public static List<DeviceStatusViewModel> GetDeviceStatusWhere(IEnumerable<Device<IStation521>> soue, Func<Device<IStation521>, bool> func)
  443. //{
  444. // var result = new List<DeviceStatusViewModel>();
  445. // result.AddRange(soue.Where(func).Select(device =>
  446. // {
  447. // return new DeviceStatusViewModel
  448. // {
  449. // CODE = device.Entity.CODE,
  450. // TASKNUM = device.Data.G_TaskId,
  451. // REQUEST = device.Data.G_Request,
  452. // PH_STATUS = device.Data.G_PhStatus,
  453. // ADDRTO = device.Data.G_GoodsEnd.ToString(),
  454. // };
  455. // }));
  456. // return result;
  457. //}
  458. ///// <summary>
  459. ///// 获取机械臂设备信息
  460. ///// </summary>
  461. ///// <param name="soue"></param>
  462. ///// <param name="func"></param>
  463. ///// <returns></returns>
  464. //public static List<DeviceStatusViewModel> GetDeviceStatusWhere(IEnumerable<Device<IRobot>> soue, Func<Device<IRobot>, bool> func)
  465. //{
  466. // var result = new List<DeviceStatusViewModel>();
  467. // result.AddRange(soue.Where(func).Select(device =>
  468. // {
  469. // return new DeviceStatusViewModel
  470. // {
  471. // CODE = device.Entity.CODE,
  472. // TASKNUM = device.Data.TaskID,
  473. // ADDRTO = device.Data.Trigger.ToString(),
  474. // };
  475. // }));
  476. // return result;
  477. //}
  478. #endregion 静态方法
  479. }
  480. }