StorageController.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. using AmrControl.ADS;
  2. using AmrControl.Common;
  3. using AmrControl.DB;
  4. using AmrControl.DB.Models;
  5. using AmrControl.Dto;
  6. using AmrControl.JGR;
  7. using AmrControl.services;
  8. using AmrControl.Vo;
  9. using Microsoft.AspNetCore.Mvc;
  10. using Newtonsoft.Json;
  11. using NPOI.OpenXmlFormats.Dml;
  12. // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
  13. namespace AmrControl.Controllers
  14. {
  15. [ApiController]
  16. public class StorageController : ControllerBase
  17. {
  18. private readonly MyDbHandler handler;
  19. public StorageController(MyDbHandler dbhandler)
  20. {
  21. handler = dbhandler;
  22. }
  23. /// <summary>
  24. /// 获取今日任务
  25. /// </summary>
  26. /// <returns></returns>
  27. [HttpGet]
  28. [Route("api/v1/storage/tasks")]
  29. public HttpStatus<List<IssueNoteDto>> GetTodayTasks()
  30. {
  31. HttpStatus<List<IssueNoteDto>> status = new HttpStatus<List<IssueNoteDto>>();
  32. status.Code = Dto.Code.Success;
  33. //status.Data = MockData.getIssueNodeDto();
  34. //return status;
  35. status.Data = handler.getIssueNodeDto();
  36. return status;
  37. }
  38. /// <summary>
  39. /// 查询物料号所属的储位信息
  40. /// </summary>
  41. /// <returns></returns>
  42. [HttpGet]
  43. [Route("api/v1/storage/location")]
  44. public HttpStatus<List<StorageBox>> QueryLocation(string materialID)
  45. {
  46. HttpStatus<List<StorageBox>> status = new HttpStatus<List<StorageBox>>();
  47. status.Code = Dto.Code.Success;
  48. status.Data = MockData.getStorageBox();
  49. return status;
  50. }
  51. /// <summary>
  52. /// 查询仓储格子的储位信息
  53. /// </summary>
  54. /// <returns></returns>
  55. [HttpGet]
  56. [Route("api/v1/storage/gridLocation")]
  57. public HttpStatus<List<StorageBox>> QueryGridLocation(int X,int Y)
  58. {
  59. HttpStatus<List<StorageBox>> status = new HttpStatus<List<StorageBox>>();
  60. status.Code = Dto.Code.Success;
  61. status.Data = MockData.getStorageBox(X, Y);
  62. return status;
  63. }
  64. /// <summary>
  65. /// 查询物料盒的RFID来返回物料盒所含物料的内容
  66. /// </summary>
  67. /// <returns></returns>
  68. [HttpGet]
  69. [Route("api/v1/storage/storageBox")]
  70. public HttpStatus<StorageBox> QueryStorageBox(string boxRFID)
  71. {
  72. HttpStatus<StorageBox> status = new HttpStatus<StorageBox>();
  73. status.Code = Dto.Code.Success;
  74. status.Data = MockData.getStorageBox().FirstOrDefault(x => x.BoxRFID == boxRFID);
  75. return status;
  76. }
  77. /// <summary>
  78. /// 出库并做数量扣除,返回出库的数量
  79. /// </summary>
  80. /// <param name="location"></param>
  81. /// <returns></returns>
  82. [HttpPost]
  83. [Route("api/v1/storage/retrieval")]
  84. public HttpStatus<List<RequireRawBom>> Retrieval([FromBody]RetrievalDto retrievalDto)
  85. {
  86. HttpStatus<List<RequireRawBom>> status = new HttpStatus<List<RequireRawBom>>();
  87. status.Code = Dto.Code.Success;
  88. //让数量和需求相满足
  89. foreach (var item in retrievalDto.RequireRawBoms)
  90. {
  91. item.ReleaseQuantity = item.DemandQuantity;
  92. }
  93. status.Data = retrievalDto.RequireRawBoms;
  94. return status;
  95. }
  96. /// <summary>
  97. /// 物料盒入库,从入库点搬进仓储,坐标会根据系统自动重新分配
  98. /// </summary>
  99. /// <param name="boxRFID"></param>
  100. /// <returns></returns>
  101. [HttpGet]
  102. [Route("api/v1/storage/moveIn")]
  103. public HttpStatus<string> StorageBoxMoveIn(string boxRFID)
  104. {
  105. HttpStatus<string> status = new HttpStatus<string>();
  106. status.Code = Dto.Code.Success;
  107. return status;
  108. }
  109. /// <summary>
  110. /// 物料盒出库,从当前仓储点搬出到捡料位
  111. /// </summary>
  112. /// <param name="boxRFID"></param>
  113. /// <returns></returns>
  114. [HttpGet]
  115. [Route("api/v1/storage/moveOut")]
  116. public HttpStatus<string> StorageBoxMoveOut(string boxRFID)
  117. {
  118. HttpStatus<string> status = new HttpStatus<string>();
  119. status.Code = Dto.Code.Success;
  120. return status;
  121. }
  122. /// <summary>
  123. /// 物料盒调仓位
  124. /// </summary>
  125. /// <param name="boxRFID"></param>
  126. /// <returns></returns>
  127. [HttpPost]
  128. [Route("api/v1/storage/moveTo")]
  129. public HttpStatus<List<KeyValuePair<int, string>>> StorageBoxMoveTo([FromBody] BoxMovingStatusDto movingStatus)
  130. {
  131. HttpStatus<List<KeyValuePair<int, string>>> status = new HttpStatus<List<KeyValuePair<int, string>>>();
  132. status.Data = new List<KeyValuePair<int, string>>();
  133. status.Data.Add(new KeyValuePair<int, string>(0, "第1步,前往目标点X1-Y2"));
  134. status.Data.Add(new KeyValuePair<int, string>(1, "第2步,抓取顶部物料盒"));
  135. status.Data.Add(new KeyValuePair<int, string>(2, "第3步,移走顶部物料盒到X2-Y3"));
  136. status.Data.Add(new KeyValuePair<int, string>(3, "第4步,放下物料盒子"));
  137. status.Data.Add(new KeyValuePair<int, string>(4, "第5步,前往目标点X1-Y2"));
  138. status.Data.Add(new KeyValuePair<int, string>(5, "第6步,抓取目标物料盒"));
  139. status.Data.Add(new KeyValuePair<int, string>(6, "第7步,前往调仓点X4-Y5"));
  140. status.Data.Add(new KeyValuePair<int, string>(7, "第7步,放下物料盒子,调仓完成"));
  141. status.Code = Dto.Code.Success;
  142. return status;
  143. }
  144. /// <summary>
  145. /// 呼叫空闲的轨道车到检料位
  146. /// </summary>
  147. /// <returns></returns>
  148. [HttpPost]
  149. [Route("api/v1/line/freeJGR")]
  150. public HttpStatus<string> CallFreeRailCar()
  151. {
  152. HttpStatus<string> status = new HttpStatus<string>();
  153. status.Code = Dto.Code.Success;
  154. return status;
  155. }
  156. /// <summary>
  157. /// 调度检料位的轨道车到工位,坐标自动感知
  158. /// </summary>
  159. /// <returns></returns>
  160. [HttpPost]
  161. [Route("api/v1/line/jgrToStation")]
  162. public HttpStatus<string> MoveRailCarToStation()
  163. {
  164. HttpStatus<string> status = new HttpStatus<string>();
  165. status.Code = Dto.Code.Success;
  166. return status;
  167. }
  168. /// <summary>
  169. /// 移动轨道车到目标点位
  170. /// </summary>
  171. /// <returns></returns>
  172. [HttpPost]
  173. [Route("api/v1/line/jgrMoveTo")]
  174. public HttpStatus<string> RailCarMoveTo([FromBody] JgrMovingDto movingDto)
  175. {
  176. HttpStatus<string> status = new HttpStatus<string>();
  177. status.Code = Dto.Code.Success;
  178. return status;
  179. }
  180. /// <summary>
  181. /// 获取仓储的信息
  182. /// </summary>
  183. /// <param name="StorageID"></param>
  184. /// <returns></returns>
  185. [HttpGet]
  186. [Route("api/v1/storage/storageStatus")]
  187. public HttpStatus<StorageStatus> GetStorageStatus(string StorageID)
  188. {
  189. HttpStatus<StorageStatus> status = new HttpStatus<StorageStatus>();
  190. status.Code = Dto.Code.Success;
  191. status.Data = new StorageStatus();
  192. status.Data.StorageName = "1号仓储柜";
  193. status.Data.TodayMoveOutCount = 10;
  194. status.Data.TodayMoveInCount = 5;
  195. status.Data.TotalLocation = 300;
  196. status.Data.FreeLocation = 280;
  197. status.Data.MaterialCount = 105;
  198. return status;
  199. }
  200. /// <summary>
  201. /// 获取捡料工位的信息,包括是否有车
  202. /// </summary>
  203. /// <param name="StorageID"></param>
  204. /// <returns></returns>
  205. [HttpGet]
  206. [Route("api/v1/storage/pickingStation")]
  207. public HttpStatus<PickingStationStatus> GetPickingStation(string StorageID)
  208. {
  209. HttpStatus<PickingStationStatus> status = new HttpStatus<PickingStationStatus>();
  210. status.Code = Dto.Code.Success;
  211. status.Data = new PickingStationStatus();
  212. status.Data.ContainsJAR = false;
  213. status.Data.ContainsBox = false;
  214. return status;
  215. }
  216. /// <summary>
  217. /// 入库接口
  218. /// </summary>
  219. /// <param name="dto"></param>
  220. /// <returns></returns>
  221. [HttpPost]
  222. [Route("/api/v1/storage/in-storage")]
  223. public HttpStatus<InStorageVO> inStroage([FromBody] InStorageDTO dto)
  224. {
  225. HttpStatus<InStorageVO> status = new();
  226. if (!string.IsNullOrEmpty(dto.carId) && !string.IsNullOrWhiteSpace(dto.carId))
  227. {
  228. //查找车辆信息
  229. List<JGR_Tc_Model> carStatus = JGRManager.GetInstance().GetJgrs();
  230. var carInfo = carStatus.Where(m => m.jgrSN == dto.carId).FirstOrDefault();
  231. if (carInfo == null)
  232. {
  233. status.Code = Dto.Code.Error;
  234. status.Msg = "非法的车辆编号信息";
  235. return status;
  236. }
  237. if (string.IsNullOrEmpty(dto.storagePos) || string.IsNullOrWhiteSpace(dto.storagePos))
  238. {
  239. status.Code = Dto.Code.Error;
  240. status.Msg = "非法的储位坐标信息";
  241. return status;
  242. }
  243. bool isOk = JGRManager.GetInstance().checkStoragePos(int.Parse(dto.storagePos.Split(',')[0]), int.Parse(dto.storagePos.Split(',')[1]));
  244. if(!isOk)
  245. {
  246. status.Code = Dto.Code.Error;
  247. status.Msg = "非法的储位坐标信息";
  248. return status;
  249. }
  250. string taskId = TaskExecManager.getInstance().genTaskId();
  251. Proxy taskProxy = new(() =>
  252. {
  253. //移动轨道车到入库位
  254. //JGRManager.GetInstance().moveCarToDestAsync(carInfo, JGRManager.GetInstance().inAmrPos[0], JGRManager.GetInstance().inAmrPos[1]);
  255. JGRManager.GetInstance().storageCarToInAsync(carInfo, dto);
  256. });
  257. TaskExecManager.getInstance().addTask(taskProxy, taskId);
  258. InStorageVO vo = new()
  259. {
  260. taskId = taskId
  261. };
  262. status.Code = Dto.Code.Success;
  263. status.Data = vo;
  264. return status;
  265. }
  266. status.Code = Dto.Code.Error;
  267. status.Msg = "非法的车辆编号信息";
  268. return status;
  269. }
  270. /// <summary>
  271. /// 判断任务是否完成
  272. /// </summary>
  273. /// <param name="taskId"></param>
  274. /// <returns></returns>
  275. [HttpGet]
  276. [Route("/api/v1/storage/check-task-completed")]
  277. public HttpStatus<bool> checkTaskCompleted([FromQuery] string taskId)
  278. {
  279. HttpStatus<bool> status = new();
  280. if (string.IsNullOrEmpty(taskId) || string.IsNullOrWhiteSpace(taskId))
  281. {
  282. status.Code = Dto.Code.Error;
  283. status.Msg = "非法的任务id信息";
  284. return status;
  285. }
  286. status.Code = Dto.Code.Success;
  287. status.Data = TaskExecManager.getInstance().checkTaskIsCompleted(taskId);
  288. return status;
  289. }
  290. /// <summary>
  291. /// 出库逻辑
  292. /// </summary>
  293. /// <param name="dto"></param>
  294. /// <returns></returns>
  295. [HttpPost]
  296. [Route("/api/v1/storage/out-storage")]
  297. public HttpStatus<OutStorageVO> outStorage([FromBody] OutStorageDTO dto)
  298. {
  299. HttpStatus<OutStorageVO> status = new();
  300. //判断仓储坐标是否存在
  301. if (string.IsNullOrEmpty(dto.storagePos) || string.IsNullOrWhiteSpace(dto.storagePos))
  302. {
  303. status.Code = Dto.Code.Error;
  304. status.Msg = "非法的储位坐标信息";
  305. return status;
  306. }
  307. ////呼叫空的轨道车到出库位置
  308. //List<JGR_Tc_Model> carStatus = JGRManager.GetInstance().GetJgrs();
  309. ////获取空的地车
  310. //JGR_Tc_Model? free_car = null;
  311. //if (carStatus != null && carStatus.Count > 0)
  312. //{
  313. // foreach (var car in carStatus)
  314. // {
  315. // if (car.jgrType == 1 && car.moveStatus == 0
  316. // && (string.IsNullOrEmpty(car.rfid)
  317. // || string.IsNullOrWhiteSpace(car.rfid)))
  318. // {
  319. // free_car = car;
  320. // }
  321. // }
  322. //}
  323. //if (free_car is null)
  324. //{
  325. // status.Code = Dto.Code.Error;
  326. // status.Msg = "没有空闲的车辆,请稍后再试";
  327. // return status;
  328. //}
  329. //JGRManager.GetInstance().moveCarToDestAsync(free_car, JGRManager.GetInstance().outAmrPos[0], JGRManager.GetInstance().outAmrPos[1]);
  330. //Thread.Sleep(200);
  331. //carStatus = JGRManager.GetInstance().GetJgrs();
  332. //if (carStatus is null)
  333. //{
  334. // status.Code = Dto.Code.Error;
  335. // status.Msg = "没有空闲的车辆,请稍后再试";
  336. // return status;
  337. //}
  338. ////获取空闲的仓储车信息
  339. //JGR_Tc_Model? storageCarInfo = storageCarInfo = carStatus.Where(m => m.jgrType == 0
  340. // && m.moveStatus == 0
  341. // && m.basketPosition == 0
  342. // && m.basketGripperStatus == 2
  343. // ).FirstOrDefault();
  344. //if(storageCarInfo == null)
  345. //{
  346. // status.Code = Dto.Code.Error;
  347. // status.Msg = "没有空闲的车辆,请稍后再试";
  348. // return status;
  349. //}
  350. //OutStorageVO vo = new()
  351. //{
  352. // taskId = Guid.NewGuid().ToString(),
  353. // carId = free_car.jgrSN
  354. //};
  355. bool isOk = JGRManager.GetInstance().checkStoragePos(int.Parse(dto.storagePos.Split(',')[0]), int.Parse(dto.storagePos.Split(',')[1]));
  356. if (!isOk)
  357. {
  358. status.Code = Dto.Code.Error;
  359. status.Msg = "非法的储位坐标信息";
  360. return status;
  361. }
  362. int dx = 0;
  363. int dy = 0;
  364. if (!string.IsNullOrEmpty(dto.stanCode)
  365. && !string.IsNullOrWhiteSpace(dto.stanCode))
  366. {
  367. var station = JGRManager.GetInstance().getStationByNo(dto.stanCode);
  368. if (station == null || station == default)
  369. {
  370. status.Code = Dto.Code.Error;
  371. status.Msg = "非法的工站编号";
  372. return status;
  373. }
  374. dx = station.positionX;
  375. dy = station.positionY;
  376. } else if (!string.IsNullOrEmpty(dto.destPos)
  377. && !string.IsNullOrWhiteSpace(dto.destPos))
  378. {
  379. dx = int.Parse(dto.destPos.Split(',')[0]);
  380. dy = int.Parse(dto.destPos.Split(',')[1]);
  381. } else
  382. {
  383. dx = JGRManager.GetInstance().selectStationPos[0];
  384. dy = JGRManager.GetInstance().selectStationPos[1];
  385. }
  386. string taskId = TaskExecManager.getInstance().genTaskId();
  387. Proxy taskProxy = new (() =>
  388. {
  389. //移动轨道车到入库位
  390. //JGRManager.GetInstance().moveCarToDestAsync(carInfo, JGRManager.GetInstance().inAmrPos[0], JGRManager.GetInstance().inAmrPos[1]);
  391. JGRManager.GetInstance().storageCarToOutAsync(dto.storagePos, dx, dy);
  392. });
  393. TaskExecManager.getInstance().addTask(taskProxy, taskId);
  394. OutStorageVO vo = new()
  395. {
  396. taskId = taskId
  397. };
  398. //获取到空的仓储车后,将仓储车信息反馈给服务端
  399. //JGRManager.GetInstance().storageCarToOutAsync(storageCarInfo, free_car.jgrSN,
  400. // dto.storagePos, dx, dy, vo.taskId);
  401. status.Code = Dto.Code.Success;
  402. status.Data = vo;
  403. return status;
  404. }
  405. /// <summary>
  406. /// 调仓处理
  407. /// </summary>
  408. /// <param name="dto"></param>
  409. /// <returns></returns>
  410. [HttpPost]
  411. [Route("/api/v1/storage/move-storage")]
  412. public HttpStatus<MoveStorageVO> moveStorage([FromBody] MoveStorageDTO dto)
  413. {
  414. HttpStatus<MoveStorageVO> status = new();
  415. //判断仓储坐标是否存在
  416. if (string.IsNullOrEmpty(dto.sourcePos)
  417. || string.IsNullOrWhiteSpace(dto.sourcePos)
  418. || string.IsNullOrEmpty(dto.destPos)
  419. || string.IsNullOrWhiteSpace(dto.destPos)
  420. || dto.sourcePos == dto.destPos)
  421. {
  422. status.Code = Dto.Code.Error;
  423. status.Msg = "非法的储位坐标信息";
  424. return status;
  425. }
  426. bool spBreak = JGRManager.GetInstance().checkStoragePos(int.Parse(dto.sourcePos.Split(',')[0]), int.Parse(dto.sourcePos.Split(',')[1]));
  427. bool dpBreak = JGRManager.GetInstance().checkStoragePos(int.Parse(dto.destPos.Split(',')[0]), int.Parse(dto.destPos.Split(',')[1]));
  428. if (!spBreak || !dpBreak)
  429. {
  430. status.Code = Dto.Code.Error;
  431. status.Msg = "非法的储位坐标信息";
  432. return status;
  433. }
  434. ////获取空闲的仓储车信息
  435. //List<JGR_Tc_Model>? carStatus = JGRManager.GetInstance().GetJgrs();
  436. //if(carStatus == null)
  437. //{
  438. // status.Code = Dto.Code.Error;
  439. // status.Msg = "未找到车辆信息";
  440. // return status;
  441. //}
  442. //JGR_Tc_Model? storageCarInfo = carStatus.Where(m => m.jgrType == 0
  443. // && m.moveStatus == 0
  444. // && m.basketPosition == 0
  445. // && m.basketGripperStatus == 2
  446. // ).FirstOrDefault();
  447. //if(storageCarInfo == null)
  448. //{
  449. // status.Code = Dto.Code.Error;
  450. // status.Msg = "没有空闲车辆";
  451. // return status;
  452. //}
  453. //MoveStorageVO vo = new()
  454. //{
  455. // taskId = Guid.NewGuid().ToString(),
  456. // carId = storageCarInfo.jgrSN
  457. //};
  458. ////获取到空的仓储车后,将仓储车信息反馈给服务端
  459. //JGRManager.GetInstance().moveStorageAsync(storageCarInfo, dto, vo.taskId);
  460. string taskId = TaskExecManager.getInstance().genTaskId();
  461. Proxy taskProxy = new(() =>
  462. {
  463. //移动轨道车到入库位
  464. //JGRManager.GetInstance().moveCarToDestAsync(carInfo, JGRManager.GetInstance().inAmrPos[0], JGRManager.GetInstance().inAmrPos[1]);
  465. JGRManager.GetInstance().moveStorageAsync(dto);
  466. });
  467. TaskExecManager.getInstance().addTask(taskProxy, taskId);
  468. MoveStorageVO vo = new()
  469. {
  470. taskId = taskId
  471. };
  472. status.Code = Dto.Code.Success;
  473. status.Data = vo;
  474. return status;
  475. }
  476. }
  477. }