diff --git a/SlnMesnac.Config/AppConfig.cs b/SlnMesnac.Config/AppConfig.cs
index c09d404..dcf0497 100644
--- a/SlnMesnac.Config/AppConfig.cs
+++ b/SlnMesnac.Config/AppConfig.cs
@@ -87,6 +87,21 @@ namespace SlnMesnac.Config
///
public string MESConfig { get; set; }
+ ///
+ /// 是否启用订单自动刷新
+ ///
+ public bool AutoOrderRefresh { get; set; } = true;
+
+ ///
+ /// 订单自动刷新间隔(秒)
+ ///
+ public int OrderRefreshInterval { get; set; } = 60;
+
+ ///
+ /// 模拟MES返回数据(调试用,配置JSON字符串)
+ ///
+ public string MockMesResponse { get; set; } = string.Empty;
+
public AppConfig Value => this;
}
}
diff --git a/SlnMesnac.Repository/service/Impl/RealReadDataImpl.cs b/SlnMesnac.Repository/service/Impl/RealReadDataImpl.cs
index 2146181..9b3c121 100644
--- a/SlnMesnac.Repository/service/Impl/RealReadDataImpl.cs
+++ b/SlnMesnac.Repository/service/Impl/RealReadDataImpl.cs
@@ -19,5 +19,14 @@ namespace SlnMesnac.Repository.service.Impl
}
public SQLiteHelper _helper = new SQLiteHelper();
+
+ /////
+ ///// 插入或者替换数据
+ /////
+ /////
+ //public bool InsertOrReplaceMesData()
+ //{
+
+ //}
}
}
diff --git a/SlnMesnac.Rfid/TouchSocketSetup.cs b/SlnMesnac.Rfid/TouchSocketSetup.cs
index 4e7e023..215dbcb 100644
--- a/SlnMesnac.Rfid/TouchSocketSetup.cs
+++ b/SlnMesnac.Rfid/TouchSocketSetup.cs
@@ -43,7 +43,7 @@ namespace SlnMesnac.TouchSocket
//var _apiServer = service.GetService();
//_apiServer.Init();
var _server = service.GetService();
- _server.Init(5656);
+ _server.Init(1145);
var _httpclient = service.GetService();
var _appSetting = service.GetService();
//_server.Init(6001);
diff --git a/SlnMesnac.TouchSocket/TcpServer.cs b/SlnMesnac.TouchSocket/TcpServer.cs
index 25a17f6..9625f07 100644
--- a/SlnMesnac.TouchSocket/TcpServer.cs
+++ b/SlnMesnac.TouchSocket/TcpServer.cs
@@ -1,5 +1,4 @@
-using Serilog;
-using SlnMesnac.Common;
+using SlnMesnac.Common;
using SlnMesnac.Model.dto;
using SlnMesnac.Model.Enum;
using SlnMesnac.Serilog;
@@ -95,19 +94,20 @@ namespace SlnMesnac.TouchSocket
};
_service.Received = (client, e) =>
{
+ Log.Information($"客户端{client.IP}发送数据 {BitConverter.ToString(e.Memory.Span.ToArray())}");
//从客户端收到信息
//var mes = Encoding.UTF8.GetString(e.Memory.Span.ToArray(), 0, e.Memory.Span.Length);//注意:数据长度是byteBlock.Len
byte[] receivedBuffer = new byte[e.Memory.Span.Length];
Array.Copy(e.Memory.Span.ToArray(), 0, receivedBuffer, 0, e.Memory.Span.Length);
//MES客户端消息解析
- if (receivedBuffer[4] == 0x65)
- {
- byte[] addrby = new byte[2];
- Array.Copy(receivedBuffer, 1, addrby, 0, 2);
- var flag = BitConverter.ToUInt16(addrby, 0);
- _service.ResetIdAsync($"{client.IP}:{client.Port}", flag.ToString());
- }
+ //if (receivedBuffer[4] == 0x65)
+ //{
+ // byte[] addrby = new byte[2];
+ // Array.Copy(receivedBuffer, 1, addrby, 0, 2);
+ // var flag = BitConverter.ToUInt16(addrby, 0);
+ // _service.ResetIdAsync($"{client.IP}:{client.Port}", flag.ToString());
+ //}
//ReceivedClientBufferEvent?.Invoke(receivedBuffer);
@@ -125,7 +125,7 @@ namespace SlnMesnac.TouchSocket
//自定义插件
}));
_service.StartAsync();
- Log.Information($"TcpServer启动成功,监听端口:{serverPort}");
+ Log.Information($"TcpServer激光打标启动成功,监听端口:{serverPort}");
Task.Run(async delegate
{
//await Task.Delay(1000 * 20);
diff --git a/SlnMesnac.WPF/ViewModel/IndexPage/ChangeTypeViewModel.cs b/SlnMesnac.WPF/ViewModel/IndexPage/ChangeTypeViewModel.cs
index 3b1ce1f..6da2f48 100644
--- a/SlnMesnac.WPF/ViewModel/IndexPage/ChangeTypeViewModel.cs
+++ b/SlnMesnac.WPF/ViewModel/IndexPage/ChangeTypeViewModel.cs
@@ -28,6 +28,7 @@ using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Forms;
+using System.Windows.Threading;
using TouchSocket.Sockets;
namespace SlnMesnac.WPF.ViewModel.IndexPage
@@ -45,6 +46,10 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
private MesOrderInfoImpl databaseService = MesOrderInfoImpl.Instance;
+ private DispatcherTimer? _autoRefreshTimer;
+ private string _currentLineName = string.Empty;
+ private bool _isPaused;
+
public ChangeTypeViewModel()
{
_logger = App.ServiceProvider.GetService();
@@ -58,6 +63,10 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
//sqlSugarClient = App.ServiceProvider.GetService();
rfidList = App.ServiceProvider.GetRequiredService>();
+ //注册订单刷新暂停/恢复消息
+ WeakReferenceMessenger.Default.Register(this, "PauseOrderRefresh", (_, __) => PauseAutoRefreshTimer());
+ WeakReferenceMessenger.Default.Register(this, "ResumeOrderRefresh", (_, __) => ResumeAutoRefreshTimer());
+
Items = new ObservableCollection();
foreach (var rfid in rfidList)
{
@@ -130,6 +139,10 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
MessageBox.Show("MES订单切换成功!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
Log.Information($"{mesOrderNo}MES订单切换成功{JsonSerializer.Serialize(real_Data)}");
+ //记录当前产线并启动自动刷新
+ _currentLineName = QueryIsCheck.ToString().Trim();
+ StartAutoRefreshTimer();
+
MainWindowViewModel.ReturnHomeAction?.Invoke();
}
@@ -152,6 +165,9 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
List DeviceInfos = appConfig.deviceInfoConfig.Where(x => x.Collectid == appConfig.StationCode && x.Name == QueryIsCheck.ToString().Trim() && x.Deleteflag == 0).ToList();
WeakReferenceMessenger.Default.Send(DeviceInfos[0].Deviceid, "Cancel");
+ //同时停止订单自动刷新
+ StopAutoRefreshTimer();
+
}
@@ -179,6 +195,8 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
//调用MES接口获取生产订单信息
//MessageBox.Show("MES订单获取成功!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
//string response = "{\"code\":200,\"msg\":\"success\",\"data\":[{\"OrderNo\":\"SS074\",\"ProductCode\":\"4030502500100006\",\"ProductType\":\"钢丝带-ST-井下阻燃钢丝带\",\"ProductName\":\"输送带-井下阻燃钢丝带-ST\",\"ProductSpec\":\"1400mm;ST/S2500*1;8+8;MT/MT;D7.2;P15;N89\",\"PlanQty\":130.00,\"NextProductNo\":1,\"PlanState\":\"7\",\"PlanStateName\":\"终止\"},{\"OrderNo\":\"SZ091\",\"ProductCode\":\"4030502000100017\",\"ProductType\":\"钢丝带-ST-井下阻燃钢丝带\",\"ProductName\":\"输送带-井下阻燃钢丝带-ST;\",\"ProductSpec\":\"1200mm;ST/S2000*1;8+6;MT/MT;D6;P12;N94\",\"PlanQty\":5.00,\"NextProductNo\":2,\"PlanState\":\"7\",\"PlanStateName\":\"终止\"},{\"OrderNo\":\"SS074\",\"ProductCode\":\"4031502500100003\",\"ProductType\":\"钢丝带-ST-井下阻燃钢网防撕裂钢丝带\",\"ProductName\":\"输送带-井下阻燃钢网防撕裂-ST\",\"ProductSpec\":\"1400mm;ST/S2500*1;8S+8;MT/MT;D7.2;P15;N89\",\"PlanQty\":160.00,\"NextProductNo\":14,\"PlanState\":\"7\",\"PlanStateName\":\"终止\"},{\"OrderNo\":\"SS074\",\"ProductCode\":\"4031502500100003\",\"ProductType\":\"钢丝带-ST-井下阻燃钢网防撕裂钢丝带\",\"ProductName\":\"输送带-井下阻燃钢网防撕裂-ST\",\"ProductSpec\":\"1400mm;ST/S2500*1;8S+8;MT/MT;D7.2;P15;N89\",\"PlanQty\":280.00,\"NextProductNo\":14,\"PlanState\":\"7\",\"PlanStateName\":\"终止\"}]}";
+ //调试用:从配置文件MockMesResponse读取模拟数据
+ //string response = appConfig.MockMesResponse;
string response = await _httpclient.GetMesOrderInfo(lineno, BeginDate.ToString("yyyy-MM-dd"));
Console.WriteLine("接收MES接口返回:" + response);
// 反序列化
@@ -202,15 +220,17 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
if (response != null)
{
- //ChangeTypePanel.Clear();
+ //先删除所有订单数据
DateTime twoDaysAgo = DateTime.Now.AddDays(-2);
- databaseService._helper.Delete(x => x.InsertDate < twoDaysAgo);
+ databaseService._helper.Delete(x => true);
+ //直接插入新的订单数据
foreach (var item in responsejson.Data)
{
item.ID = Guid.NewGuid().ToString();
item.InsertDate = DateTime.Now;
databaseService._helper.Insert(item);
}
+ //查询出来所有数据,反向之后刷新界面
var items = databaseService._helper.QueryAll();
items.Reverse();
ChangeTypePanel.Clear();
@@ -321,13 +341,171 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
set => SetProperty(ref _ChangeTypePanel, value);
}
+ #region 订单自动刷新
+
+ ///
+ /// 启动订单自动刷新定时器
+ ///
+ private void StartAutoRefreshTimer()
+ {
+ if (!appConfig.AutoOrderRefresh)
+ return;
+
+ if (_autoRefreshTimer != null)
+ return;
+
+ var intervalSeconds = appConfig.OrderRefreshInterval > 0 ? appConfig.OrderRefreshInterval : 60;
+
+ _autoRefreshTimer = new DispatcherTimer
+ {
+ Interval = TimeSpan.FromSeconds(intervalSeconds)
+ };
+ _autoRefreshTimer.Tick += AutoRefreshTimerTick;
+ _autoRefreshTimer.Start();
+ _isPaused = false;
+
+ Log.Information($"订单自动刷新已启动,间隔 {intervalSeconds} 秒");
+ }
+
+ ///
+ /// 暂停订单自动刷新(写入标签时调用)
+ ///
+ private void PauseAutoRefreshTimer()
+ {
+ if (_autoRefreshTimer == null || _isPaused)
+ return;
+
+ _autoRefreshTimer.Stop();
+ _isPaused = true;
+ Log.Information("订单自动刷新已暂停(正在写入标签)");
+ }
+
+ ///
+ /// 恢复订单自动刷新(写入完成/失败后调用)
+ ///
+ private void ResumeAutoRefreshTimer()
+ {
+ if (_autoRefreshTimer == null || !_isPaused)
+ return;
+
+ _autoRefreshTimer.Start();
+ _isPaused = false;
+ Log.Information("订单自动刷新已恢复");
+ }
+
+ ///
+ /// 停止订单自动刷新定时器
+ ///
+ public void StopAutoRefreshTimer()
+ {
+ if (_autoRefreshTimer != null)
+ {
+ _autoRefreshTimer.Stop();
+ _autoRefreshTimer = null;
+ _isPaused = false;
+ Log.Information("订单自动刷新已停止");
+ }
+ }
+
+ ///
+ /// 自动刷新定时器回调:从MES获取最新订单,发现新订单时自动执行
+ ///
+ private async void AutoRefreshTimerTick(object sender, EventArgs e)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(_currentLineName))
+ return;
+
+ //获取产线编号
+ var deviceInfos = appConfig.deviceInfoConfig
+ .Where(x => x.Collectid == appConfig.StationCode && x.Name == _currentLineName && x.Deleteflag == 0)
+ .ToList();
+ if (deviceInfos.Count == 0)
+ return;
+
+ var lineno = deviceInfos[0].Addr;
+
+ //从MES获取订单
+ //调试用:从配置文件MockMesResponse读取模拟数据
+ //var response = appConfig.MockMesResponse;
+ var response = await _httpclient.GetMesOrderInfo(lineno, DateTime.Now.ToString("yyyy-MM-dd"));
+ Log.Information($"自动刷新获取订单,产线:{_currentLineName},返回:{response}");
+
+ var responsejson = JsonSerializer.Deserialize>(
+ response, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+
+ if (responsejson?.Code != 200 || responsejson.Data == null || responsejson.Data.Count == 0)
+ return;
+
+ //查找新订单(数据库中不存在的)
+ var newOrders = new List();
+ foreach (var item in responsejson.Data)
+ {
+ var existing = databaseService._helper.Query(x => x.OrderNo == item.OrderNo && x.ProductCode == item.ProductCode);
+ if (existing == null || existing.Count == 0)
+ {
+ newOrders.Add(item);
+ }
+ }
+
+ if (newOrders.Count == 0)
+ return;
+
+ //插入新订单到数据库并刷新界面
+ foreach (var item in newOrders)
+ {
+ item.ID = Guid.NewGuid().ToString();
+ item.InsertDate = DateTime.Now;
+ databaseService._helper.Insert(item);
+ Log.Information($"自动刷新发现新订单:{item.OrderNo},物料:{item.ProductCode},自动执行");
+ }
+
+ //刷新界面显示
+ var items = databaseService._helper.QueryAll();
+ items.Reverse();
+ ChangeTypePanel.Clear();
+ foreach (var item in items)
+ {
+ ChangeTypePanel.Add(item);
+ }
+
+ //自动执行第一个新订单
+ var firstNewOrder = newOrders[0];
+ var deviceInfo = appConfig.deviceInfoConfig
+ .Where(x => x.Collectid == appConfig.StationCode && x.Name == _currentLineName && x.Deleteflag == 0)
+ .ToList();
+
+ if (deviceInfo.Count > 0)
+ {
+ var realData = new Real_DataInfo()
+ {
+ OrderNo = firstNewOrder.OrderNo,
+ Deviceid = deviceInfo[0].Deviceid,
+ LineName = _currentLineName,
+ LineNo = deviceInfo[0].Addr,
+ ProductType = firstNewOrder.ProductType,
+ RfidCount = firstNewOrder.PlanQty.ToString(),
+ NextProductNo = firstNewOrder.NextProductNo.ToString("D3")
+ };
+ WeakReferenceMessenger.Default.Send(realData);
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"订单自动刷新异常:{ex.Message}");
+ }
+ }
+
+ #endregion
+
}
}
-//0,新建
+//0, 新建
//1, 已审核
//2, 已下发
//3, 已接收
diff --git a/SlnMesnac.WPF/ViewModel/IndexPage/ProductionLineViewModel.cs b/SlnMesnac.WPF/ViewModel/IndexPage/ProductionLineViewModel.cs
index 5d92567..8e672df 100644
--- a/SlnMesnac.WPF/ViewModel/IndexPage/ProductionLineViewModel.cs
+++ b/SlnMesnac.WPF/ViewModel/IndexPage/ProductionLineViewModel.cs
@@ -241,6 +241,7 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
+ deviceInfo.NextProductNo
+ deviceInfo.SerialNo;
CurrentState = "写入中";
+ //上次读的EPC
LastRFIDEPC = tagInfos[0].EPCstring;
//写入前暂停心跳和连续盘点
@@ -248,6 +249,9 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
await rfidInfo.Set_HeartBeat(0);
Task.Delay(100).Wait();
+ //暂停订单自动刷新,防止写入过程中订单切换
+ WeakReferenceMessenger.Default.Send(string.Empty, "PauseOrderRefresh");
+
//处理写入字符串,并写入
//var originBytes = tagInfos[0].EPC.Where(b => b != 0x00).ToArray();
bool writeflag = rfidInfo.Set_Write(tagInfos[0].EPC, WriteData).GetAwaiter().GetResult();
@@ -415,6 +419,9 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
LastRFIDEPC = "";
LastWrite = "";
+ //写入完成,恢复订单自动刷新
+ WeakReferenceMessenger.Default.Send(string.Empty, "ResumeOrderRefresh");
+
await rfidInfo.Set_BeginIdentify();
await Task.Delay(100);
StartInventoryTimer(iCombineId, deviceConfig.InventoryIntervalSeconds.Value);
diff --git a/SlnMesnac.WPF/appsettings.json b/SlnMesnac.WPF/appsettings.json
index 55b5c4f..01703cd 100644
--- a/SlnMesnac.WPF/appsettings.json
+++ b/SlnMesnac.WPF/appsettings.json
@@ -125,7 +125,14 @@
"StationCode": "102",
- "MESConfig": "10.20.8.61:8001"
+ "MESConfig": "10.20.8.61:8001",
+
+ //是否启用订单自动刷新
+ "AutoOrderRefresh": true,
+ //订单自动刷新间隔(秒)
+ "OrderRefreshInterval": 60,
+ //模拟MES返回数据(调试用,为空则走真实MES接口)
+ "MockMesResponse": ""
},
"ProductConfig": {
"OKCount": "0",