using AmrControl.ADS; using AmrControl.Common; using AmrControl.DB; using AmrControl.DB.Models; using AmrControl.Dto; using AmrControl.JGR; using AmrControl.services; using AmrControl.Vo; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using NPOI.OpenXmlFormats.Dml; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace AmrControl.Controllers { [ApiController] public class StorageController : ControllerBase { private readonly MyDbHandler handler; public StorageController(MyDbHandler dbhandler) { handler = dbhandler; } /// /// 获取今日任务 /// /// [HttpGet] [Route("api/v1/storage/tasks")] public HttpStatus> GetTodayTasks() { HttpStatus> status = new HttpStatus>(); status.Code = Dto.Code.Success; //status.Data = MockData.getIssueNodeDto(); //return status; status.Data = handler.getIssueNodeDto(); return status; } /// /// 查询物料号所属的储位信息 /// /// [HttpGet] [Route("api/v1/storage/location")] public HttpStatus> QueryLocation(string materialID) { HttpStatus> status = new HttpStatus>(); status.Code = Dto.Code.Success; status.Data = MockData.getStorageBox(); return status; } /// /// 查询仓储格子的储位信息 /// /// [HttpGet] [Route("api/v1/storage/gridLocation")] public HttpStatus> QueryGridLocation(int X,int Y) { HttpStatus> status = new HttpStatus>(); status.Code = Dto.Code.Success; status.Data = MockData.getStorageBox(X, Y); return status; } /// /// 查询物料盒的RFID来返回物料盒所含物料的内容 /// /// [HttpGet] [Route("api/v1/storage/storageBox")] public HttpStatus QueryStorageBox(string boxRFID) { HttpStatus status = new HttpStatus(); status.Code = Dto.Code.Success; status.Data = MockData.getStorageBox().FirstOrDefault(x => x.BoxRFID == boxRFID); return status; } /// /// 出库并做数量扣除,返回出库的数量 /// /// /// [HttpPost] [Route("api/v1/storage/retrieval")] public HttpStatus> Retrieval([FromBody]RetrievalDto retrievalDto) { HttpStatus> status = new HttpStatus>(); status.Code = Dto.Code.Success; //让数量和需求相满足 foreach (var item in retrievalDto.RequireRawBoms) { item.ReleaseQuantity = item.DemandQuantity; } status.Data = retrievalDto.RequireRawBoms; return status; } /// /// 物料盒入库,从入库点搬进仓储,坐标会根据系统自动重新分配 /// /// /// [HttpGet] [Route("api/v1/storage/moveIn")] public HttpStatus StorageBoxMoveIn(string boxRFID) { HttpStatus status = new HttpStatus(); status.Code = Dto.Code.Success; return status; } /// /// 物料盒出库,从当前仓储点搬出到捡料位 /// /// /// [HttpGet] [Route("api/v1/storage/moveOut")] public HttpStatus StorageBoxMoveOut(string boxRFID) { HttpStatus status = new HttpStatus(); status.Code = Dto.Code.Success; return status; } /// /// 物料盒调仓位 /// /// /// [HttpPost] [Route("api/v1/storage/moveTo")] public HttpStatus>> StorageBoxMoveTo([FromBody] BoxMovingStatusDto movingStatus) { HttpStatus>> status = new HttpStatus>>(); status.Data = new List>(); status.Data.Add(new KeyValuePair(0, "第1步,前往目标点X1-Y2")); status.Data.Add(new KeyValuePair(1, "第2步,抓取顶部物料盒")); status.Data.Add(new KeyValuePair(2, "第3步,移走顶部物料盒到X2-Y3")); status.Data.Add(new KeyValuePair(3, "第4步,放下物料盒子")); status.Data.Add(new KeyValuePair(4, "第5步,前往目标点X1-Y2")); status.Data.Add(new KeyValuePair(5, "第6步,抓取目标物料盒")); status.Data.Add(new KeyValuePair(6, "第7步,前往调仓点X4-Y5")); status.Data.Add(new KeyValuePair(7, "第7步,放下物料盒子,调仓完成")); status.Code = Dto.Code.Success; return status; } /// /// 呼叫空闲的轨道车到检料位 /// /// [HttpPost] [Route("api/v1/line/freeJGR")] public HttpStatus CallFreeRailCar() { HttpStatus status = new HttpStatus(); status.Code = Dto.Code.Success; return status; } /// /// 调度检料位的轨道车到工位,坐标自动感知 /// /// [HttpPost] [Route("api/v1/line/jgrToStation")] public HttpStatus MoveRailCarToStation() { HttpStatus status = new HttpStatus(); status.Code = Dto.Code.Success; return status; } /// /// 移动轨道车到目标点位 /// /// [HttpPost] [Route("api/v1/line/jgrMoveTo")] public HttpStatus RailCarMoveTo([FromBody] JgrMovingDto movingDto) { HttpStatus status = new HttpStatus(); status.Code = Dto.Code.Success; return status; } /// /// 获取仓储的信息 /// /// /// [HttpGet] [Route("api/v1/storage/storageStatus")] public HttpStatus GetStorageStatus(string StorageID) { HttpStatus status = new HttpStatus(); status.Code = Dto.Code.Success; status.Data = new StorageStatus(); status.Data.StorageName = "1号仓储柜"; status.Data.TodayMoveOutCount = 10; status.Data.TodayMoveInCount = 5; status.Data.TotalLocation = 300; status.Data.FreeLocation = 280; status.Data.MaterialCount = 105; return status; } /// /// 获取捡料工位的信息,包括是否有车 /// /// /// [HttpGet] [Route("api/v1/storage/pickingStation")] public HttpStatus GetPickingStation(string StorageID) { HttpStatus status = new HttpStatus(); status.Code = Dto.Code.Success; status.Data = new PickingStationStatus(); status.Data.ContainsJAR = false; status.Data.ContainsBox = false; return status; } /// /// 入库接口 /// /// /// [HttpPost] [Route("/api/v1/storage/in-storage")] public HttpStatus inStroage([FromBody] InStorageDTO dto) { HttpStatus status = new(); if (!string.IsNullOrEmpty(dto.carId) && !string.IsNullOrWhiteSpace(dto.carId)) { //查找车辆信息 List carStatus = JGRManager.GetInstance().GetJgrs(); var carInfo = carStatus.Where(m => m.jgrSN == dto.carId).FirstOrDefault(); if (carInfo == null) { status.Code = Dto.Code.Error; status.Msg = "非法的车辆编号信息"; return status; } if (string.IsNullOrEmpty(dto.storagePos) || string.IsNullOrWhiteSpace(dto.storagePos)) { status.Code = Dto.Code.Error; status.Msg = "非法的储位坐标信息"; return status; } bool isOk = JGRManager.GetInstance().checkStoragePos(int.Parse(dto.storagePos.Split(',')[0]), int.Parse(dto.storagePos.Split(',')[1])); if(!isOk) { status.Code = Dto.Code.Error; status.Msg = "非法的储位坐标信息"; return status; } string taskId = TaskExecManager.getInstance().genTaskId(); Proxy taskProxy = new(() => { //移动轨道车到入库位 //JGRManager.GetInstance().moveCarToDestAsync(carInfo, JGRManager.GetInstance().inAmrPos[0], JGRManager.GetInstance().inAmrPos[1]); JGRManager.GetInstance().storageCarToInAsync(carInfo, dto); }); TaskExecManager.getInstance().addTask(taskProxy, taskId); InStorageVO vo = new() { taskId = taskId }; status.Code = Dto.Code.Success; status.Data = vo; return status; } status.Code = Dto.Code.Error; status.Msg = "非法的车辆编号信息"; return status; } /// /// 判断任务是否完成 /// /// /// [HttpGet] [Route("/api/v1/storage/check-task-completed")] public HttpStatus checkTaskCompleted([FromQuery] string taskId) { HttpStatus status = new(); if (string.IsNullOrEmpty(taskId) || string.IsNullOrWhiteSpace(taskId)) { status.Code = Dto.Code.Error; status.Msg = "非法的任务id信息"; return status; } status.Code = Dto.Code.Success; status.Data = TaskExecManager.getInstance().checkTaskIsCompleted(taskId); return status; } /// /// 出库逻辑 /// /// /// [HttpPost] [Route("/api/v1/storage/out-storage")] public HttpStatus outStorage([FromBody] OutStorageDTO dto) { HttpStatus status = new(); //判断仓储坐标是否存在 if (string.IsNullOrEmpty(dto.storagePos) || string.IsNullOrWhiteSpace(dto.storagePos)) { status.Code = Dto.Code.Error; status.Msg = "非法的储位坐标信息"; return status; } ////呼叫空的轨道车到出库位置 //List carStatus = JGRManager.GetInstance().GetJgrs(); ////获取空的地车 //JGR_Tc_Model? free_car = null; //if (carStatus != null && carStatus.Count > 0) //{ // foreach (var car in carStatus) // { // if (car.jgrType == 1 && car.moveStatus == 0 // && (string.IsNullOrEmpty(car.rfid) // || string.IsNullOrWhiteSpace(car.rfid))) // { // free_car = car; // } // } //} //if (free_car is null) //{ // status.Code = Dto.Code.Error; // status.Msg = "没有空闲的车辆,请稍后再试"; // return status; //} //JGRManager.GetInstance().moveCarToDestAsync(free_car, JGRManager.GetInstance().outAmrPos[0], JGRManager.GetInstance().outAmrPos[1]); //Thread.Sleep(200); //carStatus = JGRManager.GetInstance().GetJgrs(); //if (carStatus is null) //{ // status.Code = Dto.Code.Error; // status.Msg = "没有空闲的车辆,请稍后再试"; // return status; //} ////获取空闲的仓储车信息 //JGR_Tc_Model? storageCarInfo = storageCarInfo = carStatus.Where(m => m.jgrType == 0 // && m.moveStatus == 0 // && m.basketPosition == 0 // && m.basketGripperStatus == 2 // ).FirstOrDefault(); //if(storageCarInfo == null) //{ // status.Code = Dto.Code.Error; // status.Msg = "没有空闲的车辆,请稍后再试"; // return status; //} //OutStorageVO vo = new() //{ // taskId = Guid.NewGuid().ToString(), // carId = free_car.jgrSN //}; bool isOk = JGRManager.GetInstance().checkStoragePos(int.Parse(dto.storagePos.Split(',')[0]), int.Parse(dto.storagePos.Split(',')[1])); if (!isOk) { status.Code = Dto.Code.Error; status.Msg = "非法的储位坐标信息"; return status; } int dx = 0; int dy = 0; if (!string.IsNullOrEmpty(dto.stanCode) && !string.IsNullOrWhiteSpace(dto.stanCode)) { var station = JGRManager.GetInstance().getStationByNo(dto.stanCode); if (station == null || station == default) { status.Code = Dto.Code.Error; status.Msg = "非法的工站编号"; return status; } dx = station.positionX; dy = station.positionY; } else if (!string.IsNullOrEmpty(dto.destPos) && !string.IsNullOrWhiteSpace(dto.destPos)) { dx = int.Parse(dto.destPos.Split(',')[0]); dy = int.Parse(dto.destPos.Split(',')[1]); } else { dx = JGRManager.GetInstance().selectStationPos[0]; dy = JGRManager.GetInstance().selectStationPos[1]; } string taskId = TaskExecManager.getInstance().genTaskId(); Proxy taskProxy = new (() => { //移动轨道车到入库位 //JGRManager.GetInstance().moveCarToDestAsync(carInfo, JGRManager.GetInstance().inAmrPos[0], JGRManager.GetInstance().inAmrPos[1]); JGRManager.GetInstance().storageCarToOutAsync(dto.storagePos, dx, dy); }); TaskExecManager.getInstance().addTask(taskProxy, taskId); OutStorageVO vo = new() { taskId = taskId }; //获取到空的仓储车后,将仓储车信息反馈给服务端 //JGRManager.GetInstance().storageCarToOutAsync(storageCarInfo, free_car.jgrSN, // dto.storagePos, dx, dy, vo.taskId); status.Code = Dto.Code.Success; status.Data = vo; return status; } /// /// 调仓处理 /// /// /// [HttpPost] [Route("/api/v1/storage/move-storage")] public HttpStatus moveStorage([FromBody] MoveStorageDTO dto) { HttpStatus status = new(); //判断仓储坐标是否存在 if (string.IsNullOrEmpty(dto.sourcePos) || string.IsNullOrWhiteSpace(dto.sourcePos) || string.IsNullOrEmpty(dto.destPos) || string.IsNullOrWhiteSpace(dto.destPos) || dto.sourcePos == dto.destPos) { status.Code = Dto.Code.Error; status.Msg = "非法的储位坐标信息"; return status; } bool spBreak = JGRManager.GetInstance().checkStoragePos(int.Parse(dto.sourcePos.Split(',')[0]), int.Parse(dto.sourcePos.Split(',')[1])); bool dpBreak = JGRManager.GetInstance().checkStoragePos(int.Parse(dto.destPos.Split(',')[0]), int.Parse(dto.destPos.Split(',')[1])); if (!spBreak || !dpBreak) { status.Code = Dto.Code.Error; status.Msg = "非法的储位坐标信息"; return status; } ////获取空闲的仓储车信息 //List? carStatus = JGRManager.GetInstance().GetJgrs(); //if(carStatus == null) //{ // status.Code = Dto.Code.Error; // status.Msg = "未找到车辆信息"; // return status; //} //JGR_Tc_Model? storageCarInfo = carStatus.Where(m => m.jgrType == 0 // && m.moveStatus == 0 // && m.basketPosition == 0 // && m.basketGripperStatus == 2 // ).FirstOrDefault(); //if(storageCarInfo == null) //{ // status.Code = Dto.Code.Error; // status.Msg = "没有空闲车辆"; // return status; //} //MoveStorageVO vo = new() //{ // taskId = Guid.NewGuid().ToString(), // carId = storageCarInfo.jgrSN //}; ////获取到空的仓储车后,将仓储车信息反馈给服务端 //JGRManager.GetInstance().moveStorageAsync(storageCarInfo, dto, vo.taskId); string taskId = TaskExecManager.getInstance().genTaskId(); Proxy taskProxy = new(() => { //移动轨道车到入库位 //JGRManager.GetInstance().moveCarToDestAsync(carInfo, JGRManager.GetInstance().inAmrPos[0], JGRManager.GetInstance().inAmrPos[1]); JGRManager.GetInstance().moveStorageAsync(dto); }); TaskExecManager.getInstance().addTask(taskProxy, taskId); MoveStorageVO vo = new() { taskId = taskId }; status.Code = Dto.Code.Success; status.Data = vo; return status; } } }