using System; using System.Collections.Generic; using System.Runtime.ConstrainedExecution; using System.Web.Http; using HH.WCS.Mobox3.DSZSH.core; using HH.WCS.Mobox3.DSZSH.device; using HH.WCS.Mobox3.DSZSH.models; using HH.WCS.Mobox3.DSZSH.util; using HH.WCS.Mobox3.DSZSH.wms; using Newtonsoft.Json; using SqlSugar; using static HH.WCS.Mobox3.DSZSH.api.ApiModel; using static HH.WCS.Mobox3.DSZSH.api.OtherModel; using static HH.WCS.Mobox3.DSZSH.core.Monitor; namespace HH.WCS.Mobox3.DSZSH.api { /// /// 测试用:如果项目中要和设备对接,前期设备无法测试,用接口模拟 /// [RoutePrefix("api")] public class DebugController : ApiController { /// /// AGV状态一键回报134562 /// /// 容器号 /// [HttpPost] [Route("AGVSeriesReports")] public ReturnResults AGVSeriesReports(UpdateTaskState model) { ReturnResults returnResult = new ReturnResults(); returnResult.ResultList = new List(); var agvTaskState = new AgvTaskState() { task_no = model.TaskID, forklift_no = model.ForkliftNo, }; agvTaskState.state = 1; var temp1 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp1); agvTaskState.state = 3; var temp3 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp3); agvTaskState.state = 4; var temp4 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp4); agvTaskState.state = 5; var temp5 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp5); agvTaskState.state = 6; var temp6 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp6); agvTaskState.state = 2; var temp2 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp2); return returnResult; } [HttpPost] [Route("AgvReports")] public ReturnResults AgvReports(AgvReportsInfo model) { var db = new SqlHelper().GetInstance(); ReturnResults returnResult = new ReturnResults(); returnResult.ResultList = new List(); var agvTaskState = new AgvTaskState() { task_no = model.TaskId, forklift_no = model.ForkliftNo, }; var taskAction = db.Queryable() .Where(t => t.S_TASK_CODE == model.TaskId) .OrderBy(t => new { create = SqlFunc.Desc(t.T_CREATE) }).First(); // 最后一个Action状态 var lastState = taskAction?.N_ACTION_CODE ?? 0; if (model.NextState <= 0 || model.NextState >= 7) { LogHelper.Info("小车回报状态不在134562的范围内"); } // 0 ==> 1,3,4,5,6,2 if (lastState == 0 && model.NextState >= 1) { agvTaskState.state = 1; var temp = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp); } // 0,1 ==> 3,4,5,6,2 if (lastState < 2 && model.NextState >= 2) { agvTaskState.state = 3; var temp = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp); } // 0,1,3 ==> 4,5,6,2 if (lastState < 4 && lastState != 2 && (model.NextState >= 3 || model.NextState == 2)) { agvTaskState.state = 4; var temp = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp); } // 0,1,3,4 ==> 5,6,2 if (lastState < 5 && lastState != 2 && (model.NextState >= 4 || model.NextState == 2)) { agvTaskState.state = 5; var temp = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp); } // 0,1,3,4,5 ==> 6,2 if (lastState < 6 && lastState != 2 && (model.NextState >= 5 || model.NextState == 2)) { agvTaskState.state = 6; var temp = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp); } // 0,1,3,4,5,6 ==> 2 if (lastState != 2 && model.NextState == 2) { agvTaskState.state = 2; var temp = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp); } return returnResult; } /// /// AGV状态一键回报134 /// /// 容器号 /// [HttpPost] [Route("AGVSeriesReports14")] public ReturnResults AGVSeriesReports14(UpdateTaskState model) { var agvTaskState = new AgvTaskState() { task_no = model.TaskID, forklift_no = model.ForkliftNo, state = 1 }; ReturnResults returnResult = new ReturnResults(); returnResult.ResultList = new List(); var temp1 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp1); agvTaskState.state = 3; var temp3 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp3); agvTaskState.state = 4; var temp4 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp4); return returnResult; } /// /// AGV状态一键回报562 /// /// 容器号 /// [HttpPost] [Route("AGVSeriesReports62")] public ReturnResults AGVSeriesReports62(UpdateTaskState model) { var agvTaskState = new AgvTaskState() { task_no = model.TaskID, forklift_no = model.ForkliftNo, state = 5 }; ReturnResults returnResult = new ReturnResults(); returnResult.ResultList = new List(); var temp5 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp5); agvTaskState.state = 6; var temp6 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp6); agvTaskState.state = 2; var temp2 = WCSCore.OperateAgvTaskStatus(agvTaskState); returnResult.ResultList.Add(temp2); return returnResult; } /// /// 初始化数据库 /// /// [HttpPost] [Route("CreateDatabase")] public string CreateDatabase() { try { var db = new SqlHelper().GetInstance(); var entityTypes = new Type[] { }; //db.CodeFirst.InitTables(entityTypes); } catch (Exception ex) { LogHelper.Info($"发生了异常"); return "初始化数据库错误" + ex.Message; } return "成功"; } /// /// DEBUG:模拟输送线产线满托盘下线流程 /// /// /// [HttpPost] [Route("AddInboundTask")] public string AddInboundTask(AddInboundTaskInfo model) { var db = new SqlHelper().GetInstance(); var info = ""; const string taskName = TaskName.T托盘_满托下线入库; const string startAreaName = AreaName.B包装区; const string endAreaName = AreaName.M满托货架区; const string cntrType = "托盘"; try { var cntrCode = model.CntrCode; var startLocCode = model.StartLoc; var startLoc = db.Queryable() .Where(l => l.S_CODE == startLocCode) .Where(l => Settings.AreaMap[startAreaName].Contains(l.S_AREA_CODE)) .Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y") .Where(l => l.N_CURRENT_NUM == 0) // 绑定前 .First(); if (startLoc == null) { info = $"在'{startAreaName}'中没有找到起点货位'{startLocCode}',或不满足要求:未上锁、当前容器数量=0"; LogHelper.Info(info); return info; } var locCntrRelOld = db.Queryable() .Where(c => c.S_CNTR_CODE == cntrCode).First(); // 绑定货位和容器号 var locCntrRel = new TN_Loc_Container { S_LOC_CODE = startLocCode, S_CNTR_CODE = cntrCode, S_CNTR_TYPE = cntrType, }; startLoc.N_CURRENT_NUM = 1; // 绑定后 var endLoc = db.Queryable() .Where(a => Settings.AreaMap[endAreaName].Contains(a.S_AREA_CODE)) .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y") // 筛选:未上锁 .Where(a => a.N_CURRENT_NUM == 0) // 筛选:空货位 .OrderBy(l => l.N_LAYER) .First(); if (endLoc == null) { info = $"在终点货区'{endAreaName}'中,没有找到合适的【终点货位】,需要满足要求:未上锁、当前容器数量=0"; LogHelper.Info(info); return info; } var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockStartLoc(ref startLoc); // 起点出库锁 LocationHelper.LockEndLoc(ref endLoc); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (locCntrRelOld != null) { if (db.Deleteable(locCntrRelOld).ExecuteCommand() <= 0 && db.Updateable().SetColumns(l => l.N_CURRENT_NUM == 0).Where(l => l.S_CODE == locCntrRelOld.S_LOC_CODE).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"删除旧货位容器关系表失败:货位编码{locCntrRelOld.S_LOC_CODE},容器编码{locCntrRelOld.S_CNTR_CODE}"; LogHelper.Info(info); return info; } } if (db.Insertable(locCntrRel).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"插入货位容器关系表失败:货位编码{locCntrRel.S_LOC_CODE},容器编码{locCntrRel.S_CNTR_CODE}"; LogHelper.Info(info); return info; } if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成任务'{taskName}'失败:更新起点货位{startLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return info; } if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成任务'{taskName}'失败:更新终点货位{endLoc.S_CODE}锁状态失败"; LogHelper.Info(info); return info; } if (db.Insertable(task).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成任务'{taskName}'失败,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return info; } tran.CommitTran(); info = $"生成任务'{taskName}'成功,容器号{cntId},起点{startLoc.S_CODE},终点货架{endLoc.S_CODE}"; LogHelper.Info(info); return info; } } catch (Exception ex) { LogHelper.InfoEx(ex); return ex.Message; } } [HttpPost] [Route("TestErpSendOutboundPlan")] public ErpResult TestErpSendOutboundPlan(TestErpSendOutboundPlanInfo model) { var apiName = "ERP下发出库计划单"; //LogHelper.InfoApi(apiName, model); var erpModel = new ErpSendOutboundPlanInfo(); erpModel.jhdh = model.PlanNo; erpModel.cpdm = model.ItemCode; erpModel.pzjs = model.ItemNum; LogHelper.InfoApi(apiName, erpModel); return ApiHelper.ErpSendOutboundPlan(erpModel); } [HttpPost] [Route("PickUpReturn")] public TestErpResult PickUpReturn(PickUpReturnErpInfo model) { if (model.sfjs == 0) { return new TestErpResult { code = 1, message = "实发件数未确定" }; } return new TestErpResult { code = 0, message = "success" }; } [HttpPost] [Route("CreateTaskReturn")] public TestErpResult CreateTaskReturn(CreateTaskReturnErpInfo model) { if (model.hw == "") { return new TestErpResult { code = 1, message = "货位信息未提供" }; } return new TestErpResult { code = 0, message = "success" }; } } public class TestErpSendOutboundPlanInfo { /// /// 出库计划单号(计划单号 jhdh) /// public string PlanNo { get; set; } = string.Empty; /// /// 物料编码(产品代码 cpdm) /// public string ItemCode { get; set; } = string.Empty; /// /// 物料数量(派装件数 pzjs) /// public float ItemNum { get; set; } = 0; } public class TestErpResult { public int code { get; set; } public string message { get; set; } } public class AddInboundTaskInfo { /// /// 物料编码(暂时没用) /// public string ItemCode { get; set; } /// /// 批次号(暂时没用) /// public string BatchNo { get; set; } /// /// 容器编码 /// public string CntrCode { get; set; } /// /// 起始货位 /// public string StartLoc { get; set; } } /// /// 模拟 AGV 传递信号,用于更改任务状态 /// public class UpdateTaskState { /// /// 任务ID /// public string TaskID { set; get; } /// /// AGV 小车号 /// public string ForkliftNo { set; get; } ///// ///// AGV 下一个状态 ///// //public int NextState { set; get; } } public class AgvReportsInfo { /// /// 任务号 /// public string TaskId { set; get; } /// /// AGV 小车号 /// public string ForkliftNo { get; set; } /// /// AGV 下一状态(任务回报号) /// public int NextState { set; get; } = 0; } public class FalseOk { public bool JumpOut { set; get; } = true; } public class InsertCntrItemInfo { public string Cntr { set; get; } public string Item { set; get; } } /// /// /// public class ReturnResults { public List ResultList { set; get; } } public class LocCntrCg { public string Note { get; set; } // 仅用于备注 public string LocCode { get; set; } public string LocArea { get; set; } public string CntrCode { get; set; } public string CntrType { get; set; } public string ItemCode { get; set; } public string BatchNo { get; set; } } }