using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using GalaSoft.MvvmLight; using Microsoft.Extensions.DependencyInjection; using Serilog; using SlnMesnac.Common; using SlnMesnac.Config; using SlnMesnac.Model.domain; using SlnMesnac.Model.dto; using SlnMesnac.Model.Enum; using SlnMesnac.Repository; using SlnMesnac.Repository.service; using SlnMesnac.Rfid; using SlnMesnac.Rfid.Enum; using SlnMesnac.Serilog; using SlnMesnac.WPF.Attribute; using SlnMesnac.WPF.Model; using SqlSugar; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Threading; using TouchSocket.Core; using TouchSocket.Sockets; using static Microsoft.WindowsAPICodePack.Shell.PropertySystem.SystemProperties.System; using Task = System.Threading.Tasks.Task; namespace SlnMesnac.WPF.ViewModel.IndexPage { [RegisterAsSingletonAttribute] public class ProductionLineViewModel : ViewModelBase { private static StringChange _StringChange; private String SerialNo = ""; private SerilogHelper _logger; //容器里面的读写器集合 public List rfidList; private AppConfig appConfig; private DispatcherTimer _timer; private RealReadDataService dataService = RealReadDataService.Instance; #region 关联属性 private ObservableCollection _Deviceinfo = new ObservableCollection(); public ObservableCollection Deviceinfo { get { return _Deviceinfo; } set { _Deviceinfo = value; RaisePropertyChanged(() => Deviceinfo); } } private ObservableCollection _preparedWriteList = new ObservableCollection(); public ObservableCollection PreparedWriteList { get { return _preparedWriteList; } set { _preparedWriteList = value; RaisePropertyChanged(() => PreparedWriteList); } } private ObservableCollection _tempRecordList = new ObservableCollection(); public ObservableCollection TempRecordList { get { return _tempRecordList; } set { _tempRecordList = value; RaisePropertyChanged(() => TempRecordList); } } /// /// 日期时间 /// private DateTime _currentDateTime; public DateTime CurrentDateTime { get => _currentDateTime; set { if (_currentDateTime != value) { _currentDateTime = value; RaisePropertyChanged(() => CurrentDateTime); } } } /// /// 上一次写入状态 /// private string _lastWriteState; public string LastWriteState { get => _lastWriteState; set { if (_lastWriteState != value) { _lastWriteState = value; RaisePropertyChanged(() => LastWriteState); } } } /// /// RFID连接状态 /// private string _rfidConnectState; public string RFIDConnectState { get => _rfidConnectState; set { if (_rfidConnectState != value) { _rfidConnectState = value; RaisePropertyChanged(() => RFIDConnectState); } } } /// /// 订单号 /// private string _orderNo; public string OrderNo { get => _orderNo; set { if (_orderNo != value) { _orderNo = value; RaisePropertyChanged(() => OrderNo); } } } /// /// 产线号 /// private string _lineNo; public string LineNo { get => _lineNo; set { if (_lineNo != value) { _lineNo = value; RaisePropertyChanged(() => LineNo); } } } /// /// 带号 /// private string _bindNo; public string BindNo { get => _bindNo; set { if (_bindNo != value) { _bindNo = value; RaisePropertyChanged(() => BindNo); } } } /// /// 写入数量 /// private string _writeCount; public string WriteCount { get => _writeCount; set { if (_writeCount != value) { _writeCount = value; RaisePropertyChanged(() => WriteCount); } } } public RelayCommand GenerateCodeCommand { get; set; } public RelayCommand ListClearCommand { get; set; } public RelayCommand HistoryClearCommand { get; set; } public RelayCommand HistoryPageCommand { get; set; } public RelayCommand AutoWriteCommand { get; set; } public RelayCommand RFIDWriteCommand { get; set; } #endregion public ProductionLineViewModel() { GenerateCodeCommand = new RelayCommand(t => GenerateCode(t)); ListClearCommand = new RelayCommand(t => ListClear(t)); HistoryClearCommand = new RelayCommand(t => HistoryClear(t)); HistoryPageCommand = new RelayCommand(t => HistoryPage(t)); AutoWriteCommand = new RelayCommand(t => AutoWrite(t)); RFIDWriteCommand = new RelayCommand(t => RFIDWrite(t)); // 构造函数里注册 _StringChange = App.ServiceProvider.GetService(); _logger = App.ServiceProvider.GetService(); appConfig = App.ServiceProvider.GetService(); rfidList = App.ServiceProvider.GetRequiredService>(); rfidList.ForEach(rfid => { rfid._Action += RecvIdentifyData_Instance; //rfid._RefreshLogMessageAction += RefreshLogMessage; }); StartCheckStatus(); //GetRFIDHistoryRecords(); _currentDateTime = DateTime.Now; _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) // 每秒更新一次 }; _timer.Tick += (s, e) => { CurrentDateTime = DateTime.Now; }; _timer.Start(); Log.Information("RFID输送带系统启动"); } /// /// 编码生成 /// /// private void GenerateCode(object obj) { PreparedWriteList.Clear(); if(!int.TryParse(WriteCount, out int count)) { MessageBox.Show("请输入有效的写入数量!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } for(int i = 1; i <= count; i++) { PreparedWriteList.Add(new real_readdata() { objid = Guid.NewGuid().ToString(), orderno = OrderNo, lineno = LineNo, bindno = BindNo, serialno = i.ToString("D2"), }); } } /// /// 清除生成编码数据 /// /// private void ListClear(object obj) { } /// /// 清除历史数据 /// /// private void HistoryClear(object obj) { } /// /// 历史记录页面 /// /// private void HistoryPage(object obj) { } /// /// 自动写入 /// /// private void AutoWrite(object obj) { } /// /// 自动写入 /// /// private void RFIDWrite(object obj) { } /// /// 接收到连续盘点标签返回 /// /// /// private async void RecvIdentifyData_Instance(string iCombineId, List tagInfos) { string info = ""; try { if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo)) { MessageBox.Show("请先获取MES订单号!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //读到停止连续盘点 //bool stopflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_StopIdentify(); //查询数据库是否已存在记录 bool iflag = false; string epcascii = Encoding.ASCII.GetString(tagInfos[0].EPC); epcascii = epcascii.Replace("\0", ""); List real_Readdatas = dataService.Helper.Query(x => x.rfidascii == epcascii); //如果不存在则写入 if (real_Readdatas.Count <= 0) //if (true) { if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo)) { return; } Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); //拼接订单号写入标签 string WriteData = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo + Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo + DateTime.Now.ToString("yy") + Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).NextProductNo + Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo; //写入 三次重写 bool writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData); if (!writeflag) { Log.Error($"第一次写入失败,重试中..."); writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData); if (!writeflag) { Log.Error($"第二次写入失败,重试中..."); writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData); if (!writeflag) { Log.Error($"第三次写入失败,立即开始重新盘点"); LastWriteState = "失败"; rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult(); return; } } } Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus = "成功"; LastWriteState = "成功"; Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = WriteData; Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC = tagInfos[0].EPCstring; Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo = (Convert.ToInt32(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo) + 1).ToString("D2"); //保存写入记录 real_readdata real_Readdata = new real_readdata() { serialno = (Convert.ToInt32(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo) - 1).ToString("D2"), orderno = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo, lineno = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo, producttype = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ProductType, rfidepc = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC, rfidascii = WriteData, readtime = Convert.ToDateTime(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime), writetime = Convert.ToDateTime(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime), writestatus = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus }; var a = dataService.Helper.Insert(real_Readdata); //刷新界面 //Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = Encoding.ASCII.GetString(tagInfos[0].EPC); //Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); //RefreshEventArgs(iCombineId, tagInfos); AddRFIDData(iCombineId, tagInfos); } await Task.Run(async () => { await Task.Delay(1000); await rfidList.FirstOrDefault(x => x.deviceid == iCombineId)!.Set_BeginIdentify(); }); } catch (Exception e) { Log.Error($"读结果准备写入时异常:{e.Message}"); } finally { } } /// /// 添加数据的方法(核心:添加前/后判断行数) /// /// /// public void AddRFIDData(string iCombineId, List tagInfos) { //// 1. 判断当前行数是否>10,是则清空 //if (RFIDHistoryRecords.Count >= 10) //{ // RFIDHistoryRecords.Clear(); //} App.Current.Dispatcher.Invoke(() => { RFIDHistoryRecords.Insert(0, new RFIDRecord { OrderNumber = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo, LineNumber = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo, ProductType = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ProductType, OriginalEPC = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC, RFIDCode = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII, ReadTime = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime, WriteTime = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime, WriteStatus = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus // 模拟1条失败数据 }); //RFIDHistoryRecords.OrderByDescending(x => x.ReadTime).ToList(); }); } #region 心跳检测 private void StartCheckStatus() { Task.Run(async () => { while (true) { try { #region RFID状态 //RefreshLogMessage("检测设备状态"); var batches = SplitListIntoBatches(rfidList, 10); for (int i = 0; i < batches.Count; i++) { var currentBatch = batches[i]; // 显示当前批次信息(UI线程) Console.WriteLine($"{DateTime.Now}开始检测第{i + 1}批(共{currentBatch.Count}个设备)\r\n"); // 异步检测当前批次的设备状态(不阻塞UI) await DetectDeviceBatchAsync(currentBatch); // 批次之间的间隔(最后一批无需等待) if (i < batches.Count - 1) { Console.WriteLine($"{DateTime.Now}第{i + 1}批检测完成,共{batches.Count}批,等待{1000 / 1000}秒后检测下一批\r\n"); await Task.Delay(10); } } #endregion RFID状态 } catch (Exception ex) { Log.Information($"监听设备状态异常:{ex.Message}"); } await Task.Delay(1000 * 20); } }); } private List> SplitListIntoBatches(List sourceList, int batchSize) { var batches = new List>(); for (int i = 0; i < sourceList.Count; i += batchSize) { // 截取每批的设备(最后一批可能不足10个) var batch = sourceList.Skip(i).Take(batchSize).ToList(); batches.Add(batch); } return batches; } private async Task DetectDeviceBatchAsync(List batch) { // 并行检测当前批次的设备(可选,根据接口性能调整) var detectionTasks = batch.Select(device => DetectSingleDeviceAsync(device)); // 等待当前批次所有设备检测完成 await Task.WhenAll(detectionTasks); } private async Task DetectSingleDeviceAsync(RfidAbsractFactory device) { try { //基于心跳检测的断线重连机制 if (GloalVar.HeartBeatRecoard.TryGetValue(device.deviceid, out var value)) { if (value.AddSeconds(15) < DateTime.Now) { await Reconnect(device); RFIDConnectState = "已连接"; } } else { await Reconnect(device); RFIDConnectState = "已连接"; var res = false; //无限获取心跳返回报文 Log.Information($"准备第一次获取心跳"); res = await device.Set_HeartBeat(5); } } catch (Exception ex) { Log.Information($"更新RFID状态异常:{ex.Message}", ex); } } /// /// 无限重连 /// /// /// private async Task Reconnect(RfidAbsractFactory device) { var res = false; do { RFIDConnectState = "未连接"; Log.Information($"[{device.deviceid}]:[{device.ip}:{device.port}]连接中..."); res = await device.ConnectAsync(device.ip, device.port, device.deviceid); } while (!res); } #endregion } }