using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; 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 SlnMesnac.WPF.Page.IndexPage; 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 : ObservableObject { private static StringChange _StringChange; private String SerialNo = ""; private SerilogHelper _logger; //容器里面的读写器集合 public List rfidList; private AppConfig appConfig; private DispatcherTimer _timer; private RealReadDataService dataService = RealReadDataService.Instance; private real_readdata NowReadData; #region 关联属性 public ObservableCollection Items { get; set; } private string _QueryIsCheck = ""; public string QueryIsCheck { get { return _QueryIsCheck; } set { _QueryIsCheck = value; if (_QueryIsCheck != value) { SetProperty(ref _QueryIsCheck, value); } } } /// /// 准备写入的列表 /// private ObservableCollection _preparedWriteList = new ObservableCollection(); public ObservableCollection PreparedWriteList { get { return _preparedWriteList; } set { if (_preparedWriteList != value) { SetProperty(ref _preparedWriteList, value); } } } /// /// 写入记录 /// private ObservableCollection _tempRecordList = new ObservableCollection(); public ObservableCollection TempRecordList { get { return _tempRecordList; } set { if (_tempRecordList != value) { SetProperty(ref _tempRecordList, value); } } } /// /// 日期时间 /// private DateTime _currentDateTime; public DateTime CurrentDateTime { get => _currentDateTime; set { if (_currentDateTime != value) { SetProperty(ref _currentDateTime, value); } } } /// /// 上一次写入状态 /// private string _lastWriteState; public string LastWriteState { get => _lastWriteState; set { if (_lastWriteState != value) { SetProperty(ref _lastWriteState, value); } } } /// /// 工作状态 /// private string _workState; public string WorkState { get => _workState; set { if (_workState != value) { SetProperty(ref _workState, value); } } } /// /// RFID连接状态 /// private string _rfidConnectState; public string RFIDConnectState { get => _rfidConnectState; set { if (_rfidConnectState != value) { SetProperty(ref _rfidConnectState, value); } } } /// /// 订单号 /// private string _orderNo; public string OrderNo { get => _orderNo; set { if (_orderNo != value) { SetProperty(ref _orderNo, value); } } } /// /// 产线号 /// private string _lineNo; public string LineNo { get => _lineNo; set { if (_lineNo != value) { SetProperty(ref _lineNo, value); } } } /// /// 带号 /// private string _bindNo; public string BindNo { get => _bindNo; set { if (_bindNo != value) { SetProperty(ref _bindNo, value); } } } /// /// 写入数量 /// private string _writeCount; public string WriteCount { get => _writeCount; set { if (_writeCount != value) { SetProperty(ref _writeCount, value); } } } 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; }); LoadDeviceInfo(); StartCheckStatus(); //GetRFIDHistoryRecords(); _currentDateTime = DateTime.Now; _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) // 每秒更新一次 }; _timer.Tick += (s, e) => { CurrentDateTime = DateTime.Now; }; _timer.Start(); Items = new ObservableCollection(); foreach (var rfid in rfidList) { Items.Add(rfid.FilterData); } WorkState = "空闲"; 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++) { string writeString = OrderNo + LineNo + DateTime.Now.ToString("yy") + BindNo + i.ToString("D2"); PreparedWriteList.Add(new real_readdata() { //objid = Guid.NewGuid().ToString(), orderno = OrderNo, lineno = LineNo, bindno = BindNo, serialno = i.ToString("D2"), rfidascii = writeString, writestatus = "等待" }); } } /// /// 清除生成编码数据 /// /// private void ListClear(object obj) { if (MessageBox.Show("确认", "确定要清除已生成的数据吗?(该操作不可还原)", MessageBoxButtons.OKCancel) == DialogResult.OK) { PreparedWriteList.Clear(); } } /// /// 清除历史数据 /// /// private void HistoryClear(object obj) { if (MessageBox.Show("确认", "确定要清除本次写入的数据吗?(可在查看历史中查询以往写入的标签)", MessageBoxButtons.OKCancel) == DialogResult.OK) { TempRecordList.Clear(); } } /// /// 历史记录页面 /// /// private void HistoryPage(object obj) { HistorySearch window = new HistorySearch(); window.Show(); } /// /// 自动写入 /// /// private void AutoWrite(object obj) { //获取设备编号 if (string.IsNullOrEmpty(QueryIsCheck.ToString().Trim())) { MessageBox.Show("请选择产线!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } /// /// 手动写入 /// /// private void RFIDWrite(object obj) { try { //获取设备编号 if (string.IsNullOrEmpty(QueryIsCheck.ToString().Trim())) { MessageBox.Show("请选择产线!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } real_readdata? data; if (obj is real_readdata) { data = obj as real_readdata; NowReadData = data; } else { return; } List DeviceInfos = appConfig.deviceInfoConfig.Where(x => x.Collectid == appConfig.StationCode && x.Name == QueryIsCheck.ToString().Trim() && x.Deleteflag == 0).ToList(); rfidList.FirstOrDefault(x => x.deviceid == DeviceInfos[0].Deviceid).Set_BeginIdentify().GetAwaiter().GetResult(); WorkState = "盘点中"; } catch (Exception ex) { Log.Error($"手动写入异常:{ex.Message}"); } } /// /// 接收到连续盘点标签返回 /// 3 /// /// private async void RecvIdentifyData_Instance(string iCombineId, List tagInfos) { try { //读到停止连续盘点 bool stopflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_StopIdentify(); if (string.IsNullOrEmpty(NowReadData.serialno)) { MessageBox.Show("错误,无序列号"); return; } WorkState = "写入中"; //写入 三次重写 bool writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, NowReadData.rfidascii); if (!writeflag) { Log.Error($"第一次写入失败,重试中..."); writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, NowReadData.rfidascii); if (!writeflag) { Log.Error($"第二次写入失败,重试中..."); writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, NowReadData.rfidascii); if (!writeflag) { Log.Error($"第三次写入失败"); MessageBox.Show("三次写入失败,请重新开始盘点"); LastWriteState = "失败"; WorkState = "空闲"; return; } } } WorkState = "空闲"; NowReadData.rfidepc = tagInfos[0].EPCstring; NowReadData.writetime = DateTime.Now; NowReadData.writestatus = "已写入"; NowReadData.objid = Guid.NewGuid().ToString(); dataService.Helper.Insert(NowReadData); int.TryParse(NowReadData.serialno, out int no); App.Current.Dispatcher.Invoke(() => { TempRecordList.Add(NowReadData); PreparedWriteList[no - 1].writestatus = "已写入"; }); NowReadData = null!; LastWriteState = "成功"; } catch (Exception e) { Log.Error($"读结果准备写入时异常:{e.Message}"); } } private void LoadDeviceInfo() { List DeviceInfos = appConfig.deviceInfoConfig.Where(x => x.Collectid == appConfig.StationCode && x.Deleteflag == 0).ToList(); List real_DataInfos = new List(); foreach (var item in DeviceInfos) { Real_DataInfo real_DataInfo = new Real_DataInfo() { Name = item.Name, Deviceid = item.Deviceid, Connectstr = item.Connectstr, LineName = item.Name, LineNo = item.Addr, OrderNo = "", ProductType = "", WriteCount = "", RfidCount = "", IsOnline = "未连接", RfidASCII = "", RfidEPC = "", ReadTime = "", WriteTime = "", ProductStatus = "", WriteStatus = "", }; real_DataInfos.Add(real_DataInfo); } } #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 { 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 } }