| | |
| | | { |
| | | foreach (var item in models) |
| | | { |
| | | string str = JsonConvert.SerializeObject(models); |
| | | Log.Information("接收WMS推送的箱码信息:" + str); |
| | | // 验证任务是否已存在 |
| | | //var taskInfo = _db.Queryable<WcsOderTask>().First(w => w.OrderNo == item.OrderNo && w.SkuNo == item.SkuNo && w.LotNo == item.LotNo); |
| | | //if (taskInfo == null) |
| | | //{ |
| | | var orderAdd = new WcsOderTask() |
| | | //var taskid = _db.Queryable<WcsOderTask>().OrderByDescending(w=>w.CreateTime).First(); |
| | | //int newid = (int)taskid.Id + 1; |
| | | var orderAdd = new WcsOderTask() |
| | | { |
| | | |
| | | OrderNo = item.OrderNo, |
| | | TaskNo = "", |
| | | LotNo = item.LotNo, |
| | |
| | | BoxType = item.BoxType, |
| | | Qty = item.Qty, |
| | | TaskType = (TaskTypeEnum)item.TaskType, |
| | | CreateTime = DateTime.Now, |
| | | }; |
| | | _db.Insertable(orderAdd).ExecuteCommand(); |
| | | //} |
| | |
| | | using Dm.filter; |
| | | using DocumentFormat.OpenXml.Bibliography; |
| | | using DocumentFormat.OpenXml.Drawing.Charts; |
| | | using Elastic.Clients.Elasticsearch.Snapshot; |
| | | using Elastic.Clients.Elasticsearch.Tasks; |
| | | using Flurl.Util; |
| | | using Furion.Logging; |
| | |
| | | { |
| | | var plcConn = modDevice.PLCUtil; |
| | | |
| | | if (modDevice.DbNumber == "DB101" && modDevice.DbNumber == "DB102") |
| | | if (modDevice.DbNumber == "DB101")//&& modDevice.DbNumber == "DB102"&& (modDevice.DbNumber == "DB102"||modDevice.PlcIdIP == "10.18.51.110") |
| | | { |
| | | // 主扫交互流程 |
| | | switch (modDevice.Value.ToString()) |
| | |
| | | //是否结批箱 |
| | | if (boxInfo[0].EndLotFlag == "1" && retVal.IsSucceed) |
| | | { |
| | | // 触发结批 解绑分道 |
| | | AutoEndLot(boxInfo[0].LotNo, plcConn, "0"); |
| | | // 触发结批 分道变为结批中 |
| | | AutoEndLot(boxInfo[0].LotNo, plcConn, "2"); |
| | | } |
| | | } |
| | | else |
| | |
| | | string sqlStr2 = $"delete from WCSBoxInfoLog where IsDelete=0 and PalletNo='{palletNo}'"; |
| | | _db.Ado.ExecuteCommand(sqlStr2); |
| | | } |
| | | |
| | | // 向WMS申请巷道 |
| | | var http = new HttpService(); |
| | | string TaskNo = "", EndLocate = ""; |
| | |
| | | } |
| | | else |
| | | { |
| | | //判断是否结批中 |
| | | var (res, jiepi) = plcConn.GetPlcDBValue(checkTaskMedel.PosType, modDevice.DbNumber, checkTaskMedel.PosLot); |
| | | if (jiepi == 2)//结批中 |
| | | { |
| | | // 分道解绑,抓箱品种写入0 |
| | | var ret1 = plcConn.SetPlcDBValue(checkTaskMedel.PosTypeLot, modDevice.DbNumber, checkTaskMedel.PlcPos, "0"); |
| | | if (ret1.IsSucceed) |
| | | { |
| | | //写入流程字成功后更新分拣任务 liudl 最后一托盘申请完入库才可清空 |
| | | checkTaskMedel.OrderNo = ""; |
| | | checkTaskMedel.TaskNo = ""; |
| | | checkTaskMedel.LotNo = ""; |
| | | checkTaskMedel.SkuNo = ""; |
| | | checkTaskMedel.SkuName = ""; |
| | | checkTaskMedel.BoxType = ""; |
| | | checkTaskMedel.Qty = 0; |
| | | checkTaskMedel.PZNo = ""; |
| | | checkTaskMedel.Status = "0"; // 绑定分道 0:解绑 1:绑定 |
| | | |
| | | //更新分拣任务 |
| | | _db.Updateable(checkTaskMedel).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | // 获取入库任务信息 |
| | | var taskModel = _db.Queryable<WcsTask>().First(m => m.TaskNo == TaskNo && m.IsDelete == false && m.Status == TaskStatusEnum.Wait); |
| | | if (taskModel != null) |
| | |
| | | // 写入结批信号 |
| | | var ret = plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PosLot, "1"); |
| | | // 分道解绑,抓箱品种写入0 |
| | | var ret1 = plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PlcPos, "0"); |
| | | //var ret1 = plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PlcPos, "0"); |
| | | if (ret.IsSucceed) |
| | | { |
| | | //写入流程字成功后更新分拣任务 liudl 最后一托盘申请完入库才可清空 |
| | |
| | | //item.BoxType = ""; |
| | | //item.Qty = 0; |
| | | item.PZNo = ""; |
| | | item.Status = status; // 绑定分道 0:解绑 1:绑定 |
| | | item.Status = status; // 绑定分道 0:解绑 1:绑定 2:结批中 |
| | | |
| | | //更新分拣任务 |
| | | _db.Updateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| | |
| | | /// </summary> |
| | | public static void Init() |
| | | { |
| | | // var strMsg = new HttpService().RequestPackWcs("LN000001"); |
| | | // var strMsg = new HttpService().RequestPackWcs("LN000001"); |
| | | cts.Cancel(); |
| | | listPlc = _db.Queryable<WcsPlc>() |
| | | .Where(s => s.Type == PLCTypeEnum.StackingMachine || s.Type == PLCTypeEnum.ConveyorLine || s.Type == PLCTypeEnum.BoxConveyorLine) |
| | |
| | | { |
| | | //Console.WriteLine($"{modPlc.IP}读取{modDevice.DbNumber}.{modDevice.PlcPos}的值为:{value}"); |
| | | //无流程跳出 |
| | | if (value == 0 )// && modPlc.Type!= PLCTypeEnum.BoxConveyorLine |
| | | if (value == 0)// && modPlc.Type!= PLCTypeEnum.BoxConveyorLine |
| | | continue; |
| | | var dto = modDevice.Adapt<WcsDeviceDto>(); |
| | | dto.Value = value; |
| | |
| | | listPulish.Add(modAlarm); |
| | | } |
| | | //取消报警 |
| | | else if (value && modAlarm.Status == YesNoEnum.Y) |
| | | else if (!value && modAlarm.Status == YesNoEnum.Y) |
| | | { |
| | | modAlarm.AlarmTime = null; |
| | | modAlarm.Status = YesNoEnum.N; |
| | |
| | | modLog.Id = 0; |
| | | listLog.Add(modLog); |
| | | } |
| | | _db.Insertable(listLog).ExecuteCommand(); |
| | | if (listLog.Count >= 0) |
| | | _db.Insertable(listLog).ExecuteCommand(); |
| | | HubUtil.PublicAlarm(listPulish); |
| | | } |
| | | } |
| | |
| | | if (modPlcUtil == null) |
| | | continue; |
| | | var plcIp = modPlcUtil.PlcIP; |
| | | var listDevice = listPlcDevice.Where(s => s.PlcId == modPlcUtil.PlcId && s.DeviceType == DeviceTypeEnum.Show).ToList(); |
| | | var modPlc = listPlc.FirstOrDefault(s => s.Id == modPlcUtil.PlcId); |
| | | var listDevice = listPlcDevice.Where(s => s.PlcId == modPlcUtil.PlcId && s.DeviceType == DeviceTypeEnum.Show).ToList(); |
| | | var modPlc = listPlc.FirstOrDefault(s => s.Id == modPlcUtil.PlcId); |
| | | var listaddress = new Dictionary<string, PLCDataTypeEnum>(); |
| | | foreach (var modDevice in listDevice) |
| | | { |
| | |
| | | { |
| | | bl = false; |
| | | } |
| | | else |
| | | else |
| | | { |
| | | bl = true; |
| | | } |
| | |
| | | if (value == null) |
| | | throw Oops.Bah("未找到复位地址,请在字典管理中设置"); |
| | | PLCUtil modUtil = new PLCUtil(modPlc); |
| | | switch (input.layer) |
| | | { |
| | | case 1: |
| | | break; |
| | | case 2: |
| | | { |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, value.Value, "1"); |
| | | } |
| | | break; |
| | | case 3: |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | //switch (input.layer) |
| | | //{ |
| | | // case 1: |
| | | // modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, value.Value, "1"); |
| | | // break; |
| | | // case 2: |
| | | // { |
| | | // modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, value.Value, "1"); |
| | | // } |
| | | // break; |
| | | // case 3: |
| | | // modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, value.Value, "1"); |
| | | // break; |
| | | // default: |
| | | // break; |
| | | //} |
| | | |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, value.Value, "1"); |
| | | modUtil.Close(); |
| | | |
| | | } |
| | |
| | | [DisplayName("分页查询分拣任务表")] |
| | | public async Task<SqlSugarPagedList<WcsCheckTaskOutput>> Page(PageWcsCheckTaskInput input) |
| | | { |
| | | input.SearchKey = input.SearchKey?.Trim(); |
| | | input.SearchKey = input.SearchKey?.Trim(); |
| | | var query = _wcsCheckTaskRep.AsQueryable() |
| | | .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u => |
| | | u.OrderNo.Contains(input.SearchKey) |
| | |
| | | .WhereIF(!string.IsNullOrWhiteSpace(input.Status), u => u.Status.Contains(input.Status.Trim())) |
| | | .WhereIF(!string.IsNullOrWhiteSpace(input.PZNo), u => u.PZNo.Contains(input.PZNo.Trim())) |
| | | .WhereIF(!string.IsNullOrWhiteSpace(input.PalletNo), u => u.PalletNo.Contains(input.PalletNo.Trim())) |
| | | .WhereIF(input.BoxInsert>0, u => u.BoxInsert == input.BoxInsert) |
| | | .WhereIF(input.BoxCount>0, u => u.BoxCount == input.BoxCount) |
| | | .WhereIF(input.Qty>0, u => u.Qty == input.Qty) |
| | | .WhereIF(input.FinishQty>0, u => u.FinishQty == input.FinishQty) |
| | | .WhereIF(input.BoxInsert > 0, u => u.BoxInsert == input.BoxInsert) |
| | | .WhereIF(input.BoxCount > 0, u => u.BoxCount == input.BoxCount) |
| | | .WhereIF(input.Qty > 0, u => u.Qty == input.Qty) |
| | | .WhereIF(input.FinishQty > 0, u => u.FinishQty == input.FinishQty) |
| | | .WhereIF(input.BindTimeRange != null && input.BindTimeRange.Length == 2, u => u.BindTime >= input.BindTimeRange[0] && u.BindTime <= input.BindTimeRange[1]) |
| | | .WhereIF(input.BindUserId>0, u => u.BindUserId == input.BindUserId) |
| | | .WhereIF(input.BindUserId > 0, u => u.BindUserId == input.BindUserId) |
| | | .Select<WcsCheckTaskOutput>(); |
| | | return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize); |
| | | return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | checkTaskInfo.LotNo = taskInfo.LotNo; |
| | | checkTaskInfo.SkuNo = taskInfo.SkuNo; |
| | | checkTaskInfo.SkuName = taskInfo.SkuName; |
| | | checkTaskInfo.BoxType = taskInfo.BoxType; |
| | | //checkTaskInfo.BoxType = taskInfo.BoxType; |
| | | checkTaskInfo.Qty = taskInfo.Qty; |
| | | checkTaskInfo.Status = "1";//已绑定 |
| | | checkTaskInfo.PZNo = skuInfo.PZNo; |
| | | checkTaskInfo.PZNo = skuInfo.PZNo; |
| | | |
| | | #region#给PLC写入抓箱品种号 |
| | | var modPlc = await _wcsDeviceRep.Context.Queryable<WcsPlc>().FirstAsync(s => s.Id == deviceInfo.PlcId); |
| | | if (modPlc == null) |
| | | if (checkTaskInfo.Id >= 6) |
| | | { |
| | | throw Oops.Bah("找不到PLC信息"); |
| | | } |
| | | PLCUtil modUtil = new PLCUtil(modPlc); |
| | | if (modUtil.Connected) |
| | | { |
| | | var ret = modUtil.SetPlcDBValue(checkTaskInfo.PosType, checkTaskInfo.DbNumber, checkTaskInfo.PlcPos, checkTaskInfo.PZNo); |
| | | if (ret.IsSucceed) |
| | | var modPlc = await _wcsDeviceRep.Context.Queryable<WcsPlc>().FirstAsync(s => s.Id == deviceInfo.PlcId); |
| | | if (modPlc == null) |
| | | { |
| | | //写入流程字成功后更新分拣任务 |
| | | await _wcsCheckTaskRep.AsUpdateable(checkTaskInfo).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| | | throw Oops.Bah("找不到PLC信息"); |
| | | } |
| | | PLCUtil modUtil = new PLCUtil(modPlc); |
| | | if (modUtil.Connected) |
| | | { |
| | | var ret = modUtil.SetPlcDBValue(checkTaskInfo.PosType, checkTaskInfo.DbNumber, checkTaskInfo.PlcPos, checkTaskInfo.PZNo); |
| | | if (ret.IsSucceed) |
| | | { |
| | | //写入流程字成功后更新分拣任务 |
| | | await _wcsCheckTaskRep.AsUpdateable(checkTaskInfo).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| | | } |
| | | else |
| | | { |
| | | throw Oops.Bah("与PCL交互失败,绑定失败!"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | throw Oops.Bah("与PCL交互失败,绑定失败!"); |
| | | throw Oops.Bah("PCL未连接,绑定失败!"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | throw Oops.Bah("PCL未连接,绑定失败!"); |
| | | await _wcsCheckTaskRep.AsUpdateable(checkTaskInfo).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| | | } |
| | | #endregion |
| | | } |
| | |
| | | // throw Oops.Bah($"找不到工位号:208的设备信息"); |
| | | // } |
| | | // PLCUtil modUtil = new PLCUtil(modPlc); |
| | | |
| | | |
| | | // var ret = modUtil.SetPlcDBValue(checkTaskList2.PosTypeLot, checkTaskList2.DbNumber, checkTaskList2.PosLot, "1"); |
| | | // return; |
| | | //} |
| | |
| | | PLCUtil modUtil = new PLCUtil(modPlc); |
| | | if (modUtil.Connected) |
| | | { |
| | | var ret = modUtil.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PosLot, "0"); // 解绑分道 |
| | | if (ret.IsSucceed) |
| | | { |
| | | //写入流程字成功后更新分拣任务 |
| | | item.OrderNo = ""; |
| | | item.TaskNo = ""; |
| | | item.LotNo = ""; |
| | | item.SkuNo = ""; |
| | | item.SkuName = ""; |
| | | item.BoxType = ""; |
| | | item.Qty = 0; |
| | | item.PZNo = ""; |
| | | item.Status = "0";//未绑定 |
| | | // 写入结批信号 |
| | | var ret = modUtil.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PosLot, "1"); |
| | | //var ret1 = modUtil.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PosLot, "0"); // 解绑分道 |
| | | //if (ret1.IsSucceed) |
| | | //{ |
| | | // //写入流程字成功后更新分拣任务 |
| | | // item.OrderNo = ""; |
| | | // item.TaskNo = ""; |
| | | // item.LotNo = ""; |
| | | // item.SkuNo = ""; |
| | | // item.SkuName = ""; |
| | | // item.BoxType = ""; |
| | | // item.Qty = 0; |
| | | // item.PZNo = ""; |
| | | // item.Status = "0";//未绑定 |
| | | |
| | | //更新分拣任务 |
| | | await _wcsCheckTaskRep.AsUpdateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| | | } |
| | | else |
| | | { |
| | | throw Oops.Bah("与PCL交互失败,结批失败!"); |
| | | } |
| | | // //更新分拣任务 |
| | | // await _wcsCheckTaskRep.AsUpdateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| | | //} |
| | | //else |
| | | //{ |
| | | // throw Oops.Bah("与PCL交互失败,结批失败!"); |
| | | //} |
| | | } |
| | | else |
| | | { |
| | |
| | | #endregion |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// 任务解绑 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | [HttpPost] |
| | | [ApiDescriptionSettings(Name = "UnBindTaskForPLC")] |
| | | [DisplayName("任务解绑")] |
| | | public async Task UnBindTaskForPLC(BaseIdInput input) |
| | | { |
| | | var modCheckTask = await _wcsCheckTaskRep.AsQueryable().FirstAsync(s => s.Id == input.Id); |
| | | if (modCheckTask == null) |
| | | throw Oops.Bah("找不到该信息"); |
| | | if (modCheckTask.Status != "1") |
| | | throw Oops.Bah("该任务已解绑"); |
| | | modCheckTask.Status = "0"; |
| | | modCheckTask.OrderNo = ""; |
| | | modCheckTask.TaskNo = ""; |
| | | modCheckTask.SkuNo = ""; |
| | | modCheckTask.SkuName = ""; |
| | | modCheckTask.LotNo = ""; |
| | | modCheckTask.PZNo = ""; |
| | | modCheckTask.BoxType = ""; |
| | | modCheckTask.Qty = 0; |
| | | |
| | | await _wcsCheckTaskRep.AsUpdateable(modCheckTask).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | public class WcsDeviceTaskOrderDto |
| | | { |
| | | public long Id { get; set; } |
| | | public long TaskId { get; set; } |
| | | public string Text { get; set; } |
| | | public string? TaskNo { get; set; } |
| | | public string? OrderNo { get; set; } |
| | |
| | | private readonly SqlSugarRepository<WcsPlc> _wcsPlcRep; |
| | | private readonly SqlSugarRepository<WcsDevice> _wcsDeviceRep; |
| | | private readonly SysCacheService _sysCacheService; |
| | | public WcsDeviceService(SqlSugarRepository<WcsPlc> wcsPlcRep,SqlSugarRepository<WcsDevice> wcsDeviceRep, SysCacheService sysCacheService) |
| | | public WcsDeviceService(SqlSugarRepository<WcsPlc> wcsPlcRep, SqlSugarRepository<WcsDevice> wcsDeviceRep, SysCacheService sysCacheService) |
| | | { |
| | | _wcsPlcRep = wcsPlcRep; |
| | | _wcsDeviceRep = wcsDeviceRep; |
| | |
| | | case "suoding": // 锁定 |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Short, DbNum, "48.0", input.LocatNo); |
| | | break; |
| | | |
| | | |
| | | default: |
| | | break; |
| | | } |
| | |
| | | public async Task WriteInfo(WcsDeviceUpInfo input) |
| | | { |
| | | WcsPlc modPlc; |
| | | string DbNum = "";// DB块 |
| | | |
| | | string DbNum = "DB91";// DB块 |
| | | |
| | | if (string.IsNullOrWhiteSpace(input.LocatNo))//如果工位为空 |
| | | { |
| | | throw Oops.Bah("工位不能为空"); |
| | | } |
| | | var plcList = await _wcsPlcRep.Context.Queryable<WcsPlc>().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.IsDelete == false).ToListAsync(); |
| | | var plcList = await _wcsPlcRep.Context.Queryable<WcsPlc>().Where(s => s.Type == PLCTypeEnum.ConveyorLine).ToListAsync(); |
| | | switch (input.Layer) |
| | | { |
| | | case "1": |
| | | modPlc = plcList.FirstOrDefault(m=>m.Text == "1层托盘输送线"); |
| | | if (modPlc == null) |
| | | throw Oops.Bah($"未查询到{input.Layer}楼层PLC信息"); |
| | | DbNum = ""; |
| | | modPlc = plcList.FirstOrDefault(m => m.Text == "1层托盘输送线"); |
| | | //DbNum = ""; |
| | | break; |
| | | case "2": |
| | | modPlc = plcList.FirstOrDefault(m => m.Text == "2层托盘输送线"); |
| | | if (modPlc == null) |
| | | throw Oops.Bah($"未查询到{input.Layer}楼层PLC信息"); |
| | | DbNum = "DB91"; |
| | | //DbNum = "DB91"; |
| | | break; |
| | | case "3": |
| | | modPlc = plcList.FirstOrDefault(m => m.Text == "3层托盘输送线"); |
| | | if (modPlc == null) |
| | | throw Oops.Bah($"未查询到{input.Layer}楼层PLC信息"); |
| | | DbNum = ""; |
| | | //DbNum = ""; |
| | | break; |
| | | default: |
| | | throw Oops.Bah("楼层信息错误"); |
| | | } |
| | | |
| | | var device = await _wcsDeviceRep.Context.Queryable<WcsDevice>().FirstAsync(s => s.PlcId == modPlc.Id && s.StationNum == input.LocatNo && s.IsDelete == false && s.DeviceType == DeviceTypeEnum.Show); |
| | | if (device == null) |
| | | if (modPlc == null) |
| | | throw Oops.Bah($"未查询到{input.Layer}楼层PLC信息"); |
| | | |
| | | var device = await _wcsDeviceRep.Context.Queryable<WcsDevice>().FirstAsync(s => s.PlcId == modPlc.Id && s.StationNum == input.LocatNo && s.DeviceType == DeviceTypeEnum.Show); |
| | | if (device == null) |
| | | { |
| | | throw Oops.Bah("当前楼层未查询到该工位信息"); |
| | | } |
| | | PLCUtil modUtil = new PLCUtil(modPlc); |
| | | |
| | | |
| | | |
| | | // true : 手动模式 false:自动模式 |
| | | var (result, value) = modUtil.GetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "50.4"); |
| | | if (result.IsSucceed) |
| | | { |
| | | if (input.TypeName != "shoudong" && value.ToString().ToLower() == "false" && input.TypeName != "huifu" && input.TypeName != "UpTask" ) |
| | | if (input.TypeName != "shoudong" && value.ToString().ToLower() == "false" && input.TypeName != "huifu" && input.TypeName != "UpTask") |
| | | { |
| | | throw Oops.Bah("当前为自动模式,请先切换为手动模式"); |
| | | } |
| | |
| | | { |
| | | throw Oops.Bah("读取PLC手自动值失败"); |
| | | } |
| | | |
| | | |
| | | switch (input.TypeName) |
| | | { |
| | | case "zidong": // 自动 |
| | |
| | | { |
| | | throw Oops.Bah("事件结果错误"); |
| | | } |
| | | |
| | | |
| | | break; |
| | | case "1diandong": // 1点动 |
| | | if(input.FuncName == "true") |
| | | if (input.FuncName == "true") |
| | | { |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "50.7", "true"); |
| | | } |
| | |
| | | case "fanzhuansheng": |
| | | if (input.FuncName == "true") |
| | | { |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "51.7", "true"); |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "59.0", "true"); |
| | | } |
| | | else if (input.FuncName == "false") |
| | | { |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "51.7", "false"); |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "59.0", "false"); |
| | | } |
| | | else |
| | | { |
| | |
| | | case "fanzhuanjiang": |
| | | if (input.FuncName == "true") |
| | | { |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "52.0", "true"); |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "59.1", "true"); |
| | | } |
| | | else if (input.FuncName == "false") |
| | | { |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "52.0", "false"); |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "59.1", "false"); |
| | | } |
| | | else |
| | | { |
| | |
| | | { |
| | | throw Oops.Bah("读取PLC值失败"); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | break; |
| | | default: |
| | | break; |
| | |
| | | Thread.Sleep(1000); |
| | | modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, DbNum, "50.2", "false"); |
| | | break; |
| | | |
| | | |
| | | default: |
| | | break; |
| | | } |
| | |
| | | WcsPlc modPlc; |
| | | string DbNum = "";// DB块 |
| | | |
| | | |
| | | |
| | | var plcList = await _wcsPlcRep.Context.Queryable<WcsPlc>().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.IsDelete == false).ToListAsync(); |
| | | if (input.Layer == "1") |
| | | { |
| | |
| | | { |
| | | throw Oops.Bah("事件结果错误"); |
| | | } |
| | | break; |
| | | break; |
| | | case "TwoBoxStop": |
| | | |
| | | if (input.FuncName == "true") |
| | |
| | | { |
| | | throw Oops.Bah("操作类型信息错误"); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | #endregion |
| | |
| | | (result, var palletNo) = modConn.GetPlcDBValue(modPositionPalletNo.PosType, modDevice.DbNumber, modPositionPalletNo.PlcPos, modPositionPalletNo.StringLength); |
| | | modDevice.PalletNo = Convert.ToString(palletNo); |
| | | Console.WriteLine(modDevice.DbNumber + "." + modPositionPalletNo.PlcPos + "----------"); |
| | | } |
| | | } |
| | | if (cachePlc.Type == PLCTypeEnum.ConveyorLine || cachePlc.Type == PLCTypeEnum.StackingMachine) |
| | | { |
| | | //放货排 |
| | |
| | | (result, var pickStorey) = modConn.GetPlcDBValue(modPositionPickStorey.PosType, modDevice.DbNumber, modPositionPickStorey.PlcPos); |
| | | modDevice.PickStorey = Convert.ToInt32(pickStorey); |
| | | } |
| | | |
| | | |
| | | if (cachePlc.Type == PLCTypeEnum.StackingMachine) |
| | | { |
| | | //跺机的起始工位用取货排列层 |
| | | modDevice.StartLocatNo = $"{modDevice.PickRow.ToString().PadLeft(2,'0')}{modDevice.PickCol.ToString().PadLeft(2, '0')}{modDevice.PickStorey.ToString().PadLeft(2, '0')}"; |
| | | modDevice.StartLocatNo = $"{modDevice.PickRow.ToString().PadLeft(2, '0')}{modDevice.PickCol.ToString().PadLeft(2, '0')}{modDevice.PickStorey.ToString().PadLeft(2, '0')}"; |
| | | //跺机的目的工位用放货排列层 |
| | | modDevice.EndLocatNo = $"{modDevice.ReleaseRow.ToString().PadLeft(2, '0')}{modDevice.ReleaseCol.ToString().PadLeft(2, '0')}{modDevice.ReleaseStorey.ToString().PadLeft(2, '0')}"; |
| | | } |
| | |
| | | var modPositionEndLocatNo = listPosition.FirstOrDefault(s => s.Text == "目的工位"); |
| | | if (modPositionEndLocatNo != null) |
| | | result = modUtil.SetPlcDBValue(modPositionEndLocatNo.PosType, modDbDevice.DbNumber, modPositionEndLocatNo.PlcPos, modDevice.EndLocatNo.ToString()); |
| | | } |
| | | } |
| | | } |
| | | //托盘码 |
| | | if (modDevice.PalletNo != null) |
| | |
| | | public async Task<dynamic> WcsPackPlcList() |
| | | { |
| | | return await _wcsDeviceRep.Context.Queryable<WcsPlc>() |
| | | .Where(w => w.Type == PLCTypeEnum.RobotPalletizer || w.Type == PLCTypeEnum.StackingRobot) |
| | | .Where(w => w.Type == PLCTypeEnum.RobotPalletizer /*|| w.Type == PLCTypeEnum.StackingRobot*/) |
| | | .OrderByDescending(o => o.Type) |
| | | .Select(u => new |
| | | { |
| | |
| | | PZNo = task.PZNo, |
| | | Qty = task.Qty, |
| | | |
| | | PlcId=device.PlcId, |
| | | PlcId = device.PlcId, |
| | | Type = plc.Type |
| | | }) |
| | | .ToListAsync(); |
| | |
| | | if (modUtil.Connected) |
| | | { |
| | | connStatus = true; |
| | | } |
| | | } |
| | | foreach (var item in list) |
| | | { |
| | | item.PlcStatus = connStatus; |
| | | } |
| | | return list; |
| | | } |
| | | /// <summary> |
| | | /// 获取设备对应工位列表 |
| | | /// </summary> |
| | | /// <param name="entry"></param> |
| | | /// <returns></returns> |
| | | [HttpGet] |
| | | [ApiDescriptionSettings(Name = "WcsStackingRobotList")] |
| | | [DisplayName("获取设备对应工位列表")] |
| | | public async Task<List<WcsDeviceTaskOrderDto>> WcsStackingRobotList() |
| | | { |
| | | //var list = await _wcsDeviceRep.AsQueryable() |
| | | // .LeftJoin<WcsPlc>((a, b) => a.PlcId == b.Id) |
| | | // .Where((a, b) => a.DeviceType == DeviceTypeEnum.Business) |
| | | // .Select<WcsDeviceOutput>((a, b) => new WcsDeviceOutput() { Type = b.Type }, true) |
| | | // .ToListAsync(); |
| | | |
| | | |
| | | var list = await _wcsDeviceRep.Context.Queryable<WcsCheckTask>() |
| | | .LeftJoin<WcsDevice>((task, device) => device.StationNum == task.Port) |
| | | .InnerJoin<WcsPlc>((task, device, plc) => device.PlcId == plc.Id) |
| | | .Where((task, device, plc) => task.Id <= 3) |
| | | .OrderBy((task, device, plc) => device.CreateTime) |
| | | .Select((task, device, plc) => new WcsDeviceTaskOrderDto() |
| | | { |
| | | Id = device.Id, |
| | | TaskId = task.Id, |
| | | Text = task.Id.ToString() + "号出库分拣线", |
| | | TaskNo = task.TaskNo, |
| | | OrderNo = task.OrderNo, |
| | | LotNo = task.LotNo, |
| | | SkuNo = task.SkuNo, |
| | | SkuName = task.SkuName, |
| | | LineNo = task.LineNo, |
| | | Status = task.Status, |
| | | PZNo = task.PZNo, |
| | | Qty = task.Qty, |
| | | PlcId = device.PlcId, |
| | | Type = plc.Type |
| | | }) |
| | | .ToListAsync(); |
| | | |
| | | bool connStatus = false; |
| | | //获取设备的状态 |
| | | var modPlc = await _wcsDeviceRep.Context.Queryable<WcsPlc>().FirstAsync(s => s.Id == list[0].PlcId); |
| | | PLCUtil modUtil = new PLCUtil(modPlc); |
| | | if (modUtil.Connected) |
| | | { |
| | | connStatus = true; |
| | | } |
| | | foreach (var item in list) |
| | | { |
| | | item.PlcStatus = connStatus; |
| | |
| | | import request from '/@/utils/request'; |
| | | enum Api { |
| | | AddWcsDevice = '/api/wcsDevice/add', |
| | | DeleteWcsDevice = '/api/wcsDevice/delete', |
| | | UpdateWcsDevice = '/api/wcsDevice/update', |
| | | PageWcsDevice = '/api/wcsDevice/page', |
| | | DetailWcsDevice = '/api/wcsDevice/detail', |
| | | GetWcsPlcPlcIdDropdown = '/api/wcsDevice/WcsPlcPlcIdDropdown', |
| | | GeneratePos = '/api/wcsDevice/GeneratePos', |
| | | ListWcsDevice = '/api/wcsDevice/list', |
| | | WriteValue = '/api/wcsdevice/writeValue', |
| | | AddWcsDevice = '/api/wcsDevice/add', |
| | | DeleteWcsDevice = '/api/wcsDevice/delete', |
| | | UpdateWcsDevice = '/api/wcsDevice/update', |
| | | PageWcsDevice = '/api/wcsDevice/page', |
| | | DetailWcsDevice = '/api/wcsDevice/detail', |
| | | GetWcsPlcPlcIdDropdown = '/api/wcsDevice/WcsPlcPlcIdDropdown', |
| | | GeneratePos = '/api/wcsDevice/GeneratePos', |
| | | ListWcsDevice = '/api/wcsDevice/list', |
| | | WriteValue = '/api/wcsdevice/writeValue', |
| | | |
| | | GetWcsPackPlcList='/api/wcsDevice/WcsPackPlcList', |
| | | GetWcsPackStationPlcList='/api/wcsDevice/WcsPackStationPlcList', |
| | | BindTaskForPLC='/api/WcsCheckTask/BindTaskForPLC', |
| | | CloseTaskForPLC='/api/WcsCheckTask/CloseTaskForPLC', |
| | | GetWcsPackPlcList = '/api/wcsDevice/WcsPackPlcList', |
| | | GetWcsPackStationPlcList = '/api/wcsDevice/WcsPackStationPlcList', |
| | | GetWcsStackingRobotList = '/api/wcsDevice/WcsStackingRobotList', |
| | | BindTaskForPLC = '/api/WcsCheckTask/BindTaskForPLC', |
| | | CloseTaskForPLC = '/api/WcsCheckTask/CloseTaskForPLC', |
| | | UnBindTaskForPLC = '/api/WcsCheckTask/UnBindTaskForPLC', |
| | | |
| | | |
| | | GetLocationInfo = '/api/wcsDevice/GetLocationInfo', |
| | | WriteLocationInfo = '/api/wcsDevice/WriteLocationInfo', |
| | | WriteInfo = '/api/wcsDevice/WriteInfo', |
| | | WriteTaskInfo = '/api/wcsDevice/WriteTaskInfo', |
| | | WriteStartStop = '/api/wcsDevice/WriteStartStop', |
| | | GetLocationInfo = '/api/wcsDevice/GetLocationInfo', |
| | | WriteLocationInfo = '/api/wcsDevice/WriteLocationInfo', |
| | | WriteInfo = '/api/wcsDevice/WriteInfo', |
| | | WriteTaskInfo = '/api/wcsDevice/WriteTaskInfo', |
| | | WriteStartStop = '/api/wcsDevice/WriteStartStop', |
| | | } |
| | | // 增加设备信息 |
| | | export const WriteLocationInfo = (params?: any) => |
| | |
| | | }); |
| | | |
| | | // 删除设备信息 |
| | | export const deleteWcsDevice = (params?: any) => |
| | | export const deleteWcsDevice = (params?: any) => |
| | | request({ |
| | | url: Api.DeleteWcsDevice, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | url: Api.DeleteWcsDevice, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | |
| | | // 编辑设备信息 |
| | | export const updateWcsDevice = (params?: any) => |
| | | export const updateWcsDevice = (params?: any) => |
| | | request({ |
| | | url: Api.UpdateWcsDevice, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | url: Api.UpdateWcsDevice, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | |
| | | // 分页查询设备信息 |
| | | export const pageWcsDevice = (params?: any) => |
| | | export const pageWcsDevice = (params?: any) => |
| | | request({ |
| | | url: Api.PageWcsDevice, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | url: Api.PageWcsDevice, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | |
| | | // 详情设备信息 |
| | | export const detailWcsDevice = (id: any) => |
| | | export const detailWcsDevice = (id: any) => |
| | | request({ |
| | | url: Api.DetailWcsDevice, |
| | | method: 'get', |
| | | data: { id }, |
| | | }); |
| | | url: Api.DetailWcsDevice, |
| | | method: 'get', |
| | | data: { id }, |
| | | }); |
| | | |
| | | export const getWcsPlcPlcIdDropdown = () => |
| | | request({ |
| | | request({ |
| | | url: Api.GetWcsPlcPlcIdDropdown, |
| | | method: 'get' |
| | | }); |
| | | }); |
| | | |
| | | export const generatePos = (params?: any) => |
| | | request({ |
| | | url: Api.GeneratePos, |
| | | method: 'post', |
| | | data: params |
| | | url: Api.GeneratePos, |
| | | method: 'post', |
| | | data: params |
| | | }); |
| | | |
| | | |
| | | export const listWcsDevice = () => |
| | | request({ |
| | | url: Api.ListWcsDevice, |
| | | method: 'get' |
| | | url: Api.ListWcsDevice, |
| | | method: 'get' |
| | | }); |
| | | |
| | | |
| | |
| | | request({ |
| | | url: Api.GetWcsPackPlcList, |
| | | method: 'get' |
| | | }); |
| | | }); |
| | | |
| | | export const GetWcsPackStationPlcList = (params?: any) => |
| | | request({ |
| | | url: Api.GetWcsPackStationPlcList, |
| | | method: 'get', |
| | | data: params |
| | | }); |
| | | |
| | | }); |
| | | export const GetWcsStackingRobotList = (params?: any) => |
| | | request({ |
| | | url: Api.GetWcsStackingRobotList, |
| | | method: 'get', |
| | | data: params |
| | | }); |
| | | // 手动绑定任务到PLC |
| | | export const BindTaskForPLC = (params?: any) => |
| | | export const BindTaskForPLC = (params?: any) => |
| | | request({ |
| | | url: Api.BindTaskForPLC, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | }); |
| | | //任务结批 |
| | | export const CloseTaskForPLC = (params?: any) => |
| | | export const CloseTaskForPLC = (params?: any) => |
| | | request({ |
| | | url: Api.CloseTaskForPLC, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | }); |
| | | //任务解绑 |
| | | export const UnBindTaskForPLC = (params?: any) => |
| | | request({ |
| | | url: Api.UnBindTaskForPLC, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | //写入值 |
| | | export const writeValue = (params?: any) => |
| | | export const writeValue = (params?: any) => |
| | | request({ |
| | | url: Api.WriteValue, |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | }); |
| | |
| | | <el-table-column prop="alarmName" label="描述" align="center"></el-table-column> |
| | | <el-table-column prop="stationNum" label="位置" align="center"></el-table-column> |
| | | <el-table-column prop="alarmTime" label="时间" align="center"></el-table-column> |
| | | <el-table-column label="操作" width="80" align="center" fixed="right" show-overflow-tooltip=""> |
| | | <!-- <el-table-column label="操作" width="80" align="center" fixed="right" show-overflow-tooltip=""> |
| | | <template #default="scope"> |
| | | <el-button icon="ele-Check" size="small" text="" type="primary" |
| | | @click="topUpAlarm(scope.row)">恢复</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> --> |
| | | </el-table> |
| | | <el-pagination v-model:currentPage="tableParams.page" v-model:page-size="tableParams.pageSize" |
| | | :total="tableParams.total" :page-sizes="[10, 20, 50, 100, 200, 500]" size="small" background="" |
| | |
| | | signalR.off('PublicAlarm'); |
| | | signalR.on('PublicAlarm', (dataArray: any) => { |
| | | dataArray.forEach(data => { |
| | | console.log("1111111:"+data); |
| | | // 更新 tableData |
| | | const index = tableData.value.findIndex(t => t.id == data.id); |
| | | console.log("2222222:"+index.value); |
| | | |
| | | if (index === -1 && data.status == 1) { |
| | | // 如果不存在,添加新数据 |
New file |
| | |
| | | <template> |
| | | <el-container> |
| | | <el-col> |
| | | <el-row :span="1"> |
| | | <div class="card-page"> |
| | | <el-button |
| | | v-for="device in deviceList" |
| | | :key="device.id" |
| | | type="primary" |
| | | :plain="selectedDeviceId !== device.id" |
| | | @click="chooseDevice(device.id)" |
| | | > |
| | | {{ device.name }} |
| | | </el-button> |
| | | </div> |
| | | </el-row> |
| | | <el-row :span="1"> |
| | | <div class="card-container"> |
| | | <el-card class="other-box-card" v-for="deviceInfo in devicePointData" :key="deviceInfo.id"> |
| | | <div slot="header" class="linefix"> |
| | | <span>{{ deviceInfo.text }}</span> |
| | | <div :class="['lineStatus', { 'device-status-0': deviceInfo.plcStatus === true }, { 'device-status-1': deviceInfo.plcStatus === false }]"></div> |
| | | </div> |
| | | <div class="otherValuefix" > |
| | | <el-form label-position="left" label-width="90px"> |
| | | <el-form-item label="WMS明细单号" v-if="deviceInfo.type==5"> |
| | | <el-input v-model="deviceInfo.orderNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="任务号"> |
| | | <el-input v-model="deviceInfo.taskNo"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="批次号"> |
| | | <el-input v-model="deviceInfo.lotNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="物料编码"> |
| | | <el-input v-model="deviceInfo.skuNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="物料名称"> |
| | | <el-input v-model="deviceInfo.skuName" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="分拣线编号" v-if="deviceInfo.type==5"> |
| | | <el-input v-model="deviceInfo.lineNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="绑定状态"> |
| | | <el-input :value="deviceInfo.status === '0' ? '未绑定' : '已绑定'" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="抓箱品种"> |
| | | <el-input v-model="deviceInfo.pzNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="托盘号"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="插码箱数" v-if="deviceInfo.type==5"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="拆垛箱数" v-if="deviceInfo.type==6"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="整跺箱数"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="完成箱数"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="WMS下发数量"> |
| | | <el-input v-model="deviceInfo.qty" readonly></el-input> |
| | | </el-form-item> --> |
| | | <el-form-item label="状态"> |
| | | <el-input :value="deviceInfo.plcStatus ? '在线' : '离线'" readonly></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <!-- 设备类型为码垛机器人 --> |
| | | <div v-if="deviceInfo.type==5" class="otherButtonfix"> |
| | | <el-form label-position="left"> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="openBindDialog(deviceInfo.id)">绑定</el-button> |
| | | <el-button @click="closeBindDialog(deviceInfo.lotNo)">结批</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | </el-row> |
| | | </el-col> |
| | | |
| | | <!-- 绑定任务弹框 --> |
| | | <el-dialog v-model="bindDialogVisible" title="选择数据"> |
| | | <el-table |
| | | :data="bindData" |
| | | highlight-current-row |
| | | @row-click="handleRowClick" |
| | | > |
| | | <el-table-column prop="orderNo" label="WMS下发单号" show-overflow-tooltip="" /> |
| | | <el-table-column prop="taskNo" label="任务号" show-overflow-tooltip="" /> |
| | | <el-table-column prop="lotNo" label="批次号" show-overflow-tooltip="" /> |
| | | <el-table-column prop="skuNo" label="物料编码" show-overflow-tooltip="" /> |
| | | <el-table-column prop="skuName" label="物料名称" show-overflow-tooltip="" /> |
| | | <el-table-column prop="boxType" label="规格" show-overflow-tooltip="" /> |
| | | <el-table-column prop="qty" label="总箱数/计划箱数/预估箱数" show-overflow-tooltip="" /> |
| | | </el-table> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="bindDialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="confirmBinding">确认</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </el-container> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref, onMounted } from 'vue'; |
| | | import { GetWcsPackPlcList,GetWcsPackStationPlcList,BindTaskForPLC,CloseTaskForPLC } from '/@/api/wcs/wcsDevice'; |
| | | import { pageWcsOderTask } from '/@/api/device/wcsOderTask'; |
| | | import { ElMessageBox,ElMessage } from 'element-plus'; |
| | | import { signalR,stopConnection } from './signalR'; |
| | | //连接signalR 监听变更 |
| | | onMounted(async () => { |
| | | signalR.off('PublicCheckTask'); |
| | | signalR.on('PublicCheckTask', (data: any) => { |
| | | //todo 需要测试 |
| | | // if (data.type == 0) { |
| | | |
| | | // } |
| | | var index = devicePointData.value.findIndex(s => s.id == data.id); |
| | | if (index !== -1) { |
| | | devicePointData.value.splice(index, 1, data); |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | //设备数据 |
| | | const deviceList=ref<any>([]); |
| | | //设备对应工位数据 |
| | | const devicePointData = ref<any>([]); |
| | | //选中设备ID |
| | | const selectedDeviceId=ref<any>(); |
| | | //选中工位ID |
| | | const selectedStationId=ref<any>(); |
| | | |
| | | const bindDialogVisible = ref(false); |
| | | const bindData = ref<any>([]); |
| | | const selectedRow = ref<any>(null); |
| | | const queryParams = ref<any>({}); |
| | | const tableParams = ref({ |
| | | page: 1, |
| | | pageSize: 20, |
| | | total: 0, |
| | | }); |
| | | |
| | | //获取设备对应的工位数据 |
| | | const fetchStationData = async (plcId: any) => { |
| | | const res2 = await GetWcsPackStationPlcList({ plcId }); |
| | | devicePointData.value = res2.data.result; |
| | | }; |
| | | // 获取设备数据 |
| | | const fetchPLCDeviceData = async () => { |
| | | var res = await GetWcsPackPlcList(); |
| | | deviceList.value = res.data.result; |
| | | |
| | | if (deviceList.value.length > 0) { |
| | | selectedDeviceId.value = deviceList.value[0].id; |
| | | await fetchStationData(selectedDeviceId.value); |
| | | } |
| | | }; |
| | | fetchPLCDeviceData(); |
| | | |
| | | //切换设备 |
| | | function chooseDevice(id) { |
| | | selectedDeviceId.value = id; |
| | | fetchStationData(selectedDeviceId.value); |
| | | } |
| | | |
| | | const handleQuery = async () => { |
| | | var res = await pageWcsOderTask(Object.assign(queryParams.value, tableParams.value)); |
| | | bindData.value = res.data.result?.items ?? []; |
| | | tableParams.value.total = res.data.result?.total; |
| | | }; |
| | | //打开绑定弹框 |
| | | function openBindDialog(id) { |
| | | selectedStationId.value=null; |
| | | selectedRow.value=null; |
| | | |
| | | selectedStationId.value=id; |
| | | bindDialogVisible.value = true; |
| | | |
| | | handleQuery(); |
| | | } |
| | | //点击行时设置选中行 |
| | | function handleRowClick(row) { |
| | | selectedRow.value = row; |
| | | } |
| | | |
| | | //确认绑定操作 |
| | | function confirmBinding() { |
| | | if (selectedRow.value) { |
| | | //手动绑定任务到PLC |
| | | bindTaskForPLC(selectedStationId.value,selectedRow.value.id); |
| | | |
| | | bindDialogVisible.value = false; |
| | | } else { |
| | | ElMessage.error('请选择要绑定的任务!'); |
| | | } |
| | | } |
| | | const bindTaskForPLC = async (deviceId: any,oderTaskId:any) => { |
| | | const res = await BindTaskForPLC({ deviceId,oderTaskId }); |
| | | if(res.status==200){ |
| | | ElMessage.success('绑定成功!'); |
| | | // 刷新 |
| | | fetchStationData(selectedDeviceId.value); |
| | | } |
| | | } |
| | | //结批操作 |
| | | function closeBindDialog(lotNo){ |
| | | // if(lotNo==''){ |
| | | // ElMessage.error('该工位未绑定任务!'); |
| | | // return; |
| | | // } |
| | | ElMessageBox.confirm(`确定对该批次任务结批吗?`, '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(async () => { |
| | | closeTaskForPLC(lotNo); |
| | | }) |
| | | .catch(() => {}); |
| | | } |
| | | const closeTaskForPLC = async (lotNo: string) => { |
| | | const res = await CloseTaskForPLC({ lotNo }); |
| | | if(res.status==200){ |
| | | ElMessage.success('结批成功!'); |
| | | // 刷新 |
| | | fetchStationData(selectedDeviceId.value); |
| | | } |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .card-page { |
| | | width: 100%; |
| | | height: 50px; |
| | | display: flex; |
| | | text-align: center; |
| | | justify-content: center; |
| | | align-items: center; |
| | | text-align: center; |
| | | } |
| | | .card-page>button { |
| | | width: 150px; |
| | | height: 30px; |
| | | } |
| | | .card-container { |
| | | display: grid; |
| | | grid-template-columns: repeat(6, 1fr); |
| | | gap: 10px; |
| | | } |
| | | .other-box-card { |
| | | box-sizing: border-box; |
| | | background: linear-gradient(135deg, #66ccff, #3399ff); |
| | | } |
| | | .lineStatus{ |
| | | position: absolute; |
| | | right: 0; |
| | | float: right; |
| | | height: 20px; |
| | | width: 20px; |
| | | border-radius: 20px; |
| | | background-color: #67C23A; |
| | | } |
| | | .linefix{ |
| | | border-bottom: 1px solid rgb(197, 195, 195); |
| | | display: flex; |
| | | align-items: center; |
| | | height: 40px; |
| | | position: relative; |
| | | color: #fff; |
| | | } |
| | | .otherValuefix{ |
| | | width: 100%; |
| | | height: 540px; |
| | | padding: 10px; |
| | | border-bottom: 1px solid rgb(197, 195, 195); |
| | | } |
| | | .otherButtonfix{ |
| | | width: 100%; |
| | | height: 60px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 0; |
| | | } |
| | | .device-status-0{ |
| | | background-color: #58f709; |
| | | } |
| | | .device-status-1{ |
| | | background-color: red; |
| | | } |
| | | .dialog-footer { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | margin-top: 20px; |
| | | } |
| | | .divDisplay{ |
| | | display:none |
| | | } |
| | | </style> |
| | | |
New file |
| | |
| | | import * as SignalR from '@microsoft/signalr'; |
| | | import { getToken } from '/@/utils/axios-utils'; |
| | | |
| | | // 初始化SignalR对象 |
| | | const connection = new SignalR.HubConnectionBuilder() |
| | | .configureLogging(SignalR.LogLevel.Information) |
| | | .withUrl(`${window.__env__.VITE_API_URL}/hubs/CheckTask?token=${getToken()}`, { transport: SignalR.HttpTransportType.WebSockets, skipNegotiation: true }) |
| | | .withAutomaticReconnect({ |
| | | nextRetryDelayInMilliseconds: () => { |
| | | return 5000; // 每5秒重连一次 |
| | | }, |
| | | }) |
| | | .build(); |
| | | |
| | | connection.keepAliveIntervalInMilliseconds = 15 * 1000; // 心跳检测15s |
| | | connection.serverTimeoutInMilliseconds = 30 * 60 * 1000; // 超时时间30m |
| | | |
| | | // 启动连接 |
| | | connection.start().then(() => { |
| | | console.log('启动连接checkTask'); |
| | | }); |
| | | // 断开连接 |
| | | connection.onclose(async () => { |
| | | console.log('断开连接checkTask'); |
| | | }); |
| | | // 重连中 |
| | | connection.onreconnecting(() => { |
| | | console.log('服务器已断线checkTask'); |
| | | }); |
| | | // 重连成功 |
| | | connection.onreconnected(() => { |
| | | console.log('重连成功checkTask'); |
| | | }); |
| | | // 关闭连接的方法 |
| | | async function stopConnection() { |
| | | try { |
| | | await connection.stop(); |
| | | console.log('连接已关闭'); |
| | | } catch (error) { |
| | | console.error('关闭连接时发生错误:', error); |
| | | } |
| | | } |
| | | // connection.on('PublicPlcConn', () => {}); |
| | | |
| | | export { connection as signalR,stopConnection }; |
New file |
| | |
| | | <template> |
| | | <el-container> |
| | | <el-col> |
| | | <el-row :span="1"> |
| | | <div class="card-container"> |
| | | <el-card class="other-box-card" v-for="deviceInfo in devicePointData" :key="deviceInfo.id"> |
| | | <div slot="header" class="linefix"> |
| | | <span>{{ deviceInfo.text }}</span> |
| | | <!-- <div |
| | | :class="['lineStatus', { 'device-status-0': deviceInfo.plcStatus === true }, { 'device-status-1': deviceInfo.plcStatus === false }]"> |
| | | </div> --> |
| | | </div> |
| | | <div class="otherValuefix"> |
| | | <el-form label-position="left" label-width="90px"> |
| | | <el-form-item label="WMS明细单号"> |
| | | <el-input v-model="deviceInfo.orderNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="任务号"> |
| | | <el-input v-model="deviceInfo.taskNo"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="批次号"> |
| | | <el-input v-model="deviceInfo.lotNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="物料编码"> |
| | | <el-input v-model="deviceInfo.skuNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="物料名称"> |
| | | <el-input v-model="deviceInfo.skuName" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="分拣线编号" v-if="deviceInfo.type == 5"> |
| | | <el-input v-model="deviceInfo.lineNo" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="绑定状态"> |
| | | <el-input :value="deviceInfo.status === '0' ? '未绑定' : '已绑定'" readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="抓箱品种"> |
| | | <el-input v-model="deviceInfo.pzNo" readonly></el-input> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="托盘号"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="插码箱数" v-if="deviceInfo.type==5"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="拆垛箱数" v-if="deviceInfo.type==6"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="整跺箱数"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="完成箱数"> |
| | | <el-input readonly></el-input> |
| | | </el-form-item> --> |
| | | <!-- <el-form-item label="WMS下发数量"> |
| | | <el-input v-model="deviceInfo.qty" readonly></el-input> |
| | | </el-form-item> --> |
| | | <el-form-item label="状态"> |
| | | <el-input :value="deviceInfo.plcStatus ? '在线' : '离线'" readonly></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div class="otherButtonfix"> |
| | | <el-form label-position="left"> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="openBindDialog(deviceInfo.id)">绑定</el-button> |
| | | <el-button @click="closeBindDialog(deviceInfo.taskId)">解绑</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | </el-row> |
| | | </el-col> |
| | | |
| | | <!-- 绑定任务弹框 --> |
| | | <el-dialog v-model="bindDialogVisible" title="选择数据"> |
| | | <el-table :data="bindData" highlight-current-row @row-click="handleRowClick"> |
| | | <el-table-column prop="orderNo" label="WMS下发单号" show-overflow-tooltip="" /> |
| | | <el-table-column prop="taskNo" label="任务号" show-overflow-tooltip="" /> |
| | | <el-table-column prop="lotNo" label="批次号" show-overflow-tooltip="" /> |
| | | <el-table-column prop="skuNo" label="物料编码" show-overflow-tooltip="" /> |
| | | <el-table-column prop="skuName" label="物料名称" show-overflow-tooltip="" /> |
| | | <el-table-column prop="boxType" label="规格" show-overflow-tooltip="" /> |
| | | <el-table-column prop="qty" label="总箱数/计划箱数/预估箱数" show-overflow-tooltip="" /> |
| | | </el-table> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="bindDialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="confirmBinding">确认</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </el-container> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref, onMounted } from 'vue'; |
| | | import { GetWcsPackPlcList, GetWcsStackingRobotList, BindTaskForPLC, UnBindTaskForPLC } from '/@/api/wcs/wcsDevice'; |
| | | import { pageWcsOderTask } from '/@/api/device/wcsOderTask'; |
| | | import { ElMessageBox, ElMessage } from 'element-plus'; |
| | | import { signalR, stopConnection } from './signalR'; |
| | | //连接signalR 监听变更 |
| | | onMounted(async () => { |
| | | signalR.off('PublicCheckTask'); |
| | | signalR.on('PublicCheckTask', (data: any) => { |
| | | var index = devicePointData.value.findIndex(s => s.id == data.id); |
| | | if (index !== -1) { |
| | | devicePointData.value.splice(index, 1, data); |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | //设备对应工位数据 |
| | | const devicePointData = ref<any>([]); |
| | | //选中设备ID |
| | | const selectedDeviceId = ref<any>(); |
| | | //选中工位ID |
| | | const selectedStationId = ref<any>(); |
| | | |
| | | const bindDialogVisible = ref(false); |
| | | const bindData = ref<any>([]); |
| | | const selectedRow = ref<any>(null); |
| | | const queryParams = ref<any>({}); |
| | | const tableParams = ref({ |
| | | page: 1, |
| | | pageSize: 20, |
| | | total: 0, |
| | | }); |
| | | //获取设备对应的工位数据 |
| | | const fetchStationData = async () => { |
| | | const res2 = await GetWcsStackingRobotList(); |
| | | debugger; |
| | | devicePointData.value = res2.data.result; |
| | | }; |
| | | fetchStationData(); |
| | | |
| | | const handleQuery = async () => { |
| | | var res = await pageWcsOderTask(Object.assign(queryParams.value, tableParams.value)); |
| | | bindData.value = res.data.result?.items ?? []; |
| | | tableParams.value.total = res.data.result?.total; |
| | | }; |
| | | //打开绑定弹框 |
| | | function openBindDialog(id) { |
| | | selectedStationId.value = null; |
| | | selectedRow.value = null; |
| | | |
| | | selectedStationId.value = id; |
| | | bindDialogVisible.value = true; |
| | | |
| | | handleQuery(); |
| | | } |
| | | //点击行时设置选中行 |
| | | function handleRowClick(row) { |
| | | selectedRow.value = row; |
| | | } |
| | | |
| | | //确认绑定操作 |
| | | function confirmBinding() { |
| | | if (selectedRow.value) { |
| | | //手动绑定任务到PLC |
| | | bindTaskForPLC(selectedStationId.value, selectedRow.value.id); |
| | | |
| | | bindDialogVisible.value = false; |
| | | } else { |
| | | ElMessage.error('请选择要绑定的任务!'); |
| | | } |
| | | } |
| | | const bindTaskForPLC = async (deviceId: any, oderTaskId: any) => { |
| | | const res = await BindTaskForPLC({ deviceId, oderTaskId }); |
| | | if (res.status == 200) { |
| | | ElMessage.success('绑定成功!'); |
| | | fetchStationData(); |
| | | } |
| | | } |
| | | //解绑操作 |
| | | function closeBindDialog(id) { |
| | | debugger; |
| | | ElMessageBox.confirm(`确定对该批次任务解绑吗?`, '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(async () => { |
| | | await closeTaskForPLC(id); |
| | | }) |
| | | .catch(() => { }); |
| | | } |
| | | const closeTaskForPLC = async (id: number) => { |
| | | const res = await UnBindTaskForPLC({ id }); |
| | | if (res.status == 200) { |
| | | ElMessage.success('解绑成功!'); |
| | | fetchStationData(); |
| | | } |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .card-page { |
| | | width: 100%; |
| | | height: 50px; |
| | | display: flex; |
| | | text-align: center; |
| | | justify-content: center; |
| | | align-items: center; |
| | | text-align: center; |
| | | } |
| | | |
| | | .card-page>button { |
| | | width: 150px; |
| | | height: 30px; |
| | | } |
| | | |
| | | .card-container { |
| | | display: grid; |
| | | grid-template-columns: repeat(6, 1fr); |
| | | gap: 10px; |
| | | } |
| | | |
| | | .other-box-card { |
| | | box-sizing: border-box; |
| | | background: linear-gradient(135deg, #66ccff, #3399ff); |
| | | } |
| | | |
| | | .lineStatus { |
| | | position: absolute; |
| | | right: 0; |
| | | float: right; |
| | | height: 20px; |
| | | width: 20px; |
| | | border-radius: 20px; |
| | | background-color: #67C23A; |
| | | } |
| | | |
| | | .linefix { |
| | | border-bottom: 1px solid rgb(197, 195, 195); |
| | | display: flex; |
| | | align-items: center; |
| | | height: 40px; |
| | | position: relative; |
| | | color: #fff; |
| | | } |
| | | |
| | | .otherValuefix { |
| | | width: 100%; |
| | | height: 540px; |
| | | padding: 10px; |
| | | border-bottom: 1px solid rgb(197, 195, 195); |
| | | } |
| | | |
| | | .otherButtonfix { |
| | | width: 100%; |
| | | height: 60px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 0; |
| | | } |
| | | |
| | | .device-status-0 { |
| | | background-color: #58f709; |
| | | } |
| | | |
| | | .device-status-1 { |
| | | background-color: red; |
| | | } |
| | | |
| | | .dialog-footer { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .divDisplay { |
| | | display: none |
| | | } |
| | | </style> |
New file |
| | |
| | | import * as SignalR from '@microsoft/signalr'; |
| | | import { getToken } from '/@/utils/axios-utils'; |
| | | |
| | | // 初始化SignalR对象 |
| | | const connection = new SignalR.HubConnectionBuilder() |
| | | .configureLogging(SignalR.LogLevel.Information) |
| | | .withUrl(`${window.__env__.VITE_API_URL}/hubs/CheckTask?token=${getToken()}`, { transport: SignalR.HttpTransportType.WebSockets, skipNegotiation: true }) |
| | | .withAutomaticReconnect({ |
| | | nextRetryDelayInMilliseconds: () => { |
| | | return 5000; // 每5秒重连一次 |
| | | }, |
| | | }) |
| | | .build(); |
| | | |
| | | connection.keepAliveIntervalInMilliseconds = 15 * 1000; // 心跳检测15s |
| | | connection.serverTimeoutInMilliseconds = 30 * 60 * 1000; // 超时时间30m |
| | | |
| | | // 启动连接 |
| | | connection.start().then(() => { |
| | | console.log('启动连接checkTask'); |
| | | }); |
| | | // 断开连接 |
| | | connection.onclose(async () => { |
| | | console.log('断开连接checkTask'); |
| | | }); |
| | | // 重连中 |
| | | connection.onreconnecting(() => { |
| | | console.log('服务器已断线checkTask'); |
| | | }); |
| | | // 重连成功 |
| | | connection.onreconnected(() => { |
| | | console.log('重连成功checkTask'); |
| | | }); |
| | | // 关闭连接的方法 |
| | | async function stopConnection() { |
| | | try { |
| | | await connection.stop(); |
| | | console.log('连接已关闭'); |
| | | } catch (error) { |
| | | console.error('关闭连接时发生错误:', error); |
| | | } |
| | | } |
| | | // connection.on('PublicPlcConn', () => {}); |
| | | |
| | | export { connection as signalR,stopConnection }; |