From 88483b38ada2cc1492889503fc2880919e9a1131 Mon Sep 17 00:00:00 2001 From: Tyrone CT Date: Thu, 29 Jan 2026 22:15:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=B7=B2=E7=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FATrace.App/App.config | 2 + FATrace.App/FSqlContext.cs | 2 +- FATrace.App/frmMain.Designer.cs | 140 ++++- FATrace.App/frmMain.cs | 125 +++- FATrace.Model/RawProUse.cs | 1 + FATrace.WPLApp/Services/DataServices.cs | 188 +++++- FATrace.WPLApp/Services/LogService.cs | 20 +- FATrace.WPLApp/Services/SysRunService.cs | 40 ++ .../ViewModels/DashboardViewModel.cs | 54 -- FATrace.WPLApp/Views/DashboardView.xaml | 533 ++++++++++-------- FATrace.WPLApp/Views/FootView.xaml | 40 +- FATrace.WPLApp/Views/RawProInputView.xaml | 46 +- FATrace.WPLApp/Views/RawProUseView.xaml | 47 +- 13 files changed, 860 insertions(+), 378 deletions(-) diff --git a/FATrace.App/App.config b/FATrace.App/App.config index 4681fcc..839c226 100644 --- a/FATrace.App/App.config +++ b/FATrace.App/App.config @@ -8,6 +8,8 @@ + + \ No newline at end of file diff --git a/FATrace.App/FSqlContext.cs b/FATrace.App/FSqlContext.cs index 304adaf..3b11e32 100644 --- a/FATrace.App/FSqlContext.cs +++ b/FATrace.App/FSqlContext.cs @@ -16,7 +16,7 @@ namespace FATrace.App { return new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, connectionString) - .UseAutoSyncStructure(true) + .UseAutoSyncStructure(false) .Build(); } catch (Exception ex) diff --git a/FATrace.App/frmMain.Designer.cs b/FATrace.App/frmMain.Designer.cs index ffa9113..0862f4d 100644 --- a/FATrace.App/frmMain.Designer.cs +++ b/FATrace.App/frmMain.Designer.cs @@ -48,7 +48,16 @@ namespace FATrace.App btnHistoryData = new Button(); TabControlMain = new TabControl(); tabPage2 = new TabPage(); + panel4 = new Panel(); + btnConfigSave = new Button(); + label30 = new Label(); + pictureBox5 = new PictureBox(); + txtWeightDown = new TextBox(); + label29 = new Label(); + label31 = new Label(); + txtWeightUp = new TextBox(); panel3 = new Panel(); + btnReprint = new Button(); pictureBox4 = new PictureBox(); btnWeightPrint = new Button(); txtCode = new TextBox(); @@ -105,7 +114,6 @@ namespace FATrace.App dtpSearchStartTime = new DateTimePicker(); dataGridView1 = new DataGridView(); label22 = new Label(); - btnReprint = new Button(); statusStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit(); splitContainer1.Panel1.SuspendLayout(); @@ -114,6 +122,8 @@ namespace FATrace.App ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); TabControlMain.SuspendLayout(); tabPage2.SuspendLayout(); + panel4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox5).BeginInit(); panel3.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox4).BeginInit(); panel2.SuspendLayout(); @@ -333,6 +343,7 @@ namespace FATrace.App // // tabPage2 // + tabPage2.Controls.Add(panel4); tabPage2.Controls.Add(panel3); tabPage2.Controls.Add(panel2); tabPage2.Controls.Add(panel1); @@ -344,6 +355,96 @@ namespace FATrace.App tabPage2.TabIndex = 1; tabPage2.UseVisualStyleBackColor = true; // + // panel4 + // + panel4.BorderStyle = BorderStyle.FixedSingle; + panel4.Controls.Add(btnConfigSave); + panel4.Controls.Add(label30); + panel4.Controls.Add(pictureBox5); + panel4.Controls.Add(txtWeightDown); + panel4.Controls.Add(label29); + panel4.Controls.Add(label31); + panel4.Controls.Add(txtWeightUp); + panel4.Dock = DockStyle.Bottom; + panel4.Location = new Point(3, 559); + panel4.Name = "panel4"; + panel4.Size = new Size(878, 131); + panel4.TabIndex = 4; + // + // btnConfigSave + // + btnConfigSave.Font = new Font("微软雅黑", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134); + btnConfigSave.ForeColor = SystemColors.ControlDarkDark; + btnConfigSave.Location = new Point(670, 70); + btnConfigSave.Name = "btnConfigSave"; + btnConfigSave.Size = new Size(190, 44); + btnConfigSave.TabIndex = 18; + btnConfigSave.Text = "保存并使用"; + btnConfigSave.UseVisualStyleBackColor = true; + btnConfigSave.Click += btnConfigSave_Click; + // + // label30 + // + label30.AutoSize = true; + label30.Font = new Font("Microsoft YaHei UI", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134); + label30.ForeColor = SystemColors.WindowFrame; + label30.Location = new Point(149, 64); + label30.Name = "label30"; + label30.Size = new Size(82, 26); + label30.TabIndex = 19; + label30.Text = "下限(g):"; + // + // pictureBox5 + // + pictureBox5.BackgroundImageLayout = ImageLayout.None; + pictureBox5.Image = Properties.Resources.原料需求; + pictureBox5.Location = new Point(5, 7); + pictureBox5.Name = "pictureBox5"; + pictureBox5.Size = new Size(35, 35); + pictureBox5.SizeMode = PictureBoxSizeMode.StretchImage; + pictureBox5.TabIndex = 21; + pictureBox5.TabStop = false; + // + // txtWeightDown + // + txtWeightDown.Font = new Font("Microsoft YaHei UI", 12F); + txtWeightDown.Location = new Point(231, 63); + txtWeightDown.Name = "txtWeightDown"; + txtWeightDown.Size = new Size(76, 28); + txtWeightDown.TabIndex = 18; + txtWeightDown.Text = "0"; + // + // label29 + // + label29.AutoSize = true; + label29.Font = new Font("Microsoft YaHei UI", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134); + label29.ForeColor = SystemColors.WindowFrame; + label29.Location = new Point(329, 64); + label29.Name = "label29"; + label29.Size = new Size(82, 26); + label29.TabIndex = 16; + label29.Text = "上限(g):"; + // + // label31 + // + label31.AutoSize = true; + label31.Font = new Font("Microsoft YaHei UI", 18F, FontStyle.Bold); + label31.ForeColor = SystemColors.ControlDarkDark; + label31.Location = new Point(42, 9); + label31.Name = "label31"; + label31.Size = new Size(110, 31); + label31.TabIndex = 20; + label31.Text = "称重配置"; + // + // txtWeightUp + // + txtWeightUp.Font = new Font("Microsoft YaHei UI", 12F); + txtWeightUp.Location = new Point(414, 63); + txtWeightUp.Name = "txtWeightUp"; + txtWeightUp.Size = new Size(76, 28); + txtWeightUp.TabIndex = 15; + txtWeightUp.Text = "200"; + // // panel3 // panel3.BorderStyle = BorderStyle.FixedSingle; @@ -362,6 +463,18 @@ namespace FATrace.App panel3.Size = new Size(878, 176); panel3.TabIndex = 3; // + // btnReprint + // + btnReprint.Font = new Font("微软雅黑", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134); + btnReprint.ForeColor = SystemColors.ControlDarkDark; + btnReprint.Location = new Point(670, 5); + btnReprint.Name = "btnReprint"; + btnReprint.Size = new Size(190, 44); + btnReprint.TabIndex = 17; + btnReprint.Text = "重新打印当前"; + btnReprint.UseVisualStyleBackColor = true; + btnReprint.Click += btnReprint_Click; + // // pictureBox4 // pictureBox4.BackgroundImageLayout = ImageLayout.None; @@ -488,7 +601,7 @@ namespace FATrace.App lblRawUseStateTip.BackColor = Color.LightSalmon; lblRawUseStateTip.Font = new Font("Microsoft YaHei UI", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134); lblRawUseStateTip.ForeColor = SystemColors.ButtonHighlight; - lblRawUseStateTip.Location = new Point(159, 102); + lblRawUseStateTip.Location = new Point(168, 106); lblRawUseStateTip.Name = "lblRawUseStateTip"; lblRawUseStateTip.Size = new Size(247, 34); lblRawUseStateTip.TabIndex = 11; @@ -984,18 +1097,6 @@ namespace FATrace.App label22.Text = "历史数据"; label22.TextAlign = ContentAlignment.MiddleCenter; // - // btnReprint - // - btnReprint.Font = new Font("微软雅黑", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134); - btnReprint.ForeColor = SystemColors.ControlDarkDark; - btnReprint.Location = new Point(670, 5); - btnReprint.Name = "btnReprint"; - btnReprint.Size = new Size(190, 44); - btnReprint.TabIndex = 17; - btnReprint.Text = "重新打印当前"; - btnReprint.UseVisualStyleBackColor = true; - btnReprint.Click += btnReprint_Click; - // // frmMain // AutoScaleDimensions = new SizeF(7F, 17F); @@ -1020,6 +1121,9 @@ namespace FATrace.App ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); TabControlMain.ResumeLayout(false); tabPage2.ResumeLayout(false); + panel4.ResumeLayout(false); + panel4.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox5).EndInit(); panel3.ResumeLayout(false); panel3.PerformLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox4).EndInit(); @@ -1119,5 +1223,13 @@ namespace FATrace.App private TextBox txtOpName; private Label label28; private Button btnReprint; + private Label label29; + private TextBox txtWeightUp; + private Label label30; + private TextBox txtWeightDown; + private Panel panel4; + private PictureBox pictureBox5; + private Label label31; + private Button btnConfigSave; } } \ No newline at end of file diff --git a/FATrace.App/frmMain.cs b/FATrace.App/frmMain.cs index 16a2a28..a457ec0 100644 --- a/FATrace.App/frmMain.cs +++ b/FATrace.App/frmMain.cs @@ -1,7 +1,9 @@ using FATrace.App.Model; +using FATrace.Com; using FATrace.Model; using NLog; using System.Data; +using System.Globalization; using System.Net.NetworkInformation; using System.Text; @@ -193,6 +195,16 @@ namespace FATrace.App public string CurrentOperationNoUserLevel { get; set; } = string.Empty; + /// + /// 称重上限 + /// + private double WeightUp { get; set; } + + /// + /// 称重下限 + /// + private double WeightDown { get; set; } + /// /// 计算扫描 Task /// @@ -220,6 +232,18 @@ namespace FATrace.App var scaleIp = "192.168.0.80"; // 仪表的 TCP Server IP(示例值,实际请替换) var scalePort = 10251; // 仪表的 TCP Server 端口(示例值,实际请替换) + if (double.TryParse(ConfigHelper.GetStringOrDefault("WeightUp", "10"), out var weightUp)) + { + WeightUp = weightUp; + } + if (double.TryParse(ConfigHelper.GetStringOrDefault("WeightDown", "200"), out var weightDown)) + { + WeightDown = weightDown; + } + + txtWeightUp.Text = weightUp.ToString(); + txtWeightDown.Text = weightDown.ToString(); + //日产量初始获取信息 CurDayCount = GetDayCount(); @@ -324,6 +348,8 @@ namespace FATrace.App } } + CurDaySgl.CurDay = DateTime.Now.ToString("yyyy-MM-dd"); + // 每30秒检测一次服务器与打印机 loop = (loop + 1) % 1000000; if (loop % 10 == 0) @@ -662,6 +688,22 @@ namespace FATrace.App return; } + if (WeightDown > 0 && WeightUp > 0) + { + if (CurWeight < WeightDown || CurWeight > WeightUp) + { + DialogResult resultRangeCheck = frmMessage.ShowConfirm($"检测到当前重量 {CurWeight:0.###}g 不在配置范围 [{WeightDown:0.###}g, {WeightUp:0.###}g] 内,确定要【打印】操作吗?", "确认操作", this); + if (resultRangeCheck == DialogResult.Cancel) + { + return; + } + else + { + logger.Info("你打印了一个不在配置范围内的重量!!!"); + } + } + } + //确认数据 // 显示消息框,并等待用户响应 DialogResult result = frmMessage.ShowConfirm("确定要【打印】操作吗?", "确认操作", this); @@ -670,16 +712,16 @@ namespace FATrace.App return; } - if (CurWeight < 2.0) - { - //确认数据 - // 显示消息框,并等待用户响应 - DialogResult resultWeightCheck = frmMessage.ShowConfirm("检测到当前的重量小于2g,确定要【打印】操作吗?", "确认操作", this); - if (resultWeightCheck == DialogResult.Cancel) - { - return; - } - } + //if (CurWeight < 2.0) + //{ + // //确认数据 + // // 显示消息框,并等待用户响应 + // DialogResult resultWeightCheck = frmMessage.ShowConfirm("检测到当前的重量小于2g,确定要【打印】操作吗?", "确认操作", this); + // if (resultWeightCheck == DialogResult.Cancel) + // { + // return; + // } + //} //新的剩余重量 Kg @@ -811,6 +853,7 @@ namespace FATrace.App var CurDayCountInfo = FSqlContext.FDb.Select().Where(a => a.DayInfo == DateTime.Now.ToString("yyyy-MM-dd")).First(); if (CurDayCountInfo == null) { + logger.Info($"日产量信息不存在,新建日产量信息"); //当日的日产量信息不存在,第一次的话就新建信息 var ReturnData = FSqlContext.FDb.Insert(new DayCount() { @@ -1337,8 +1380,68 @@ namespace FATrace.App { logger.Error(String.Format("ErrSource : {0} ErrMsg : {1}", ex.StackTrace.ToString(), ex.Message.ToString())); } - + + } + + /// + /// 保存配置到Config并使用 + /// + /// + /// + private void btnConfigSave_Click(object sender, EventArgs e) + { + try + { + var downText = (txtWeightDown.Text ?? string.Empty).Trim(); + var upText = (txtWeightUp.Text ?? string.Empty).Trim(); + + if (string.IsNullOrWhiteSpace(downText) || + !double.TryParse(downText.Replace(',', '.').Replace('。', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var down) || down <= 0) + { + MessageBox.Show("请输入有效的下限(g),必须为正数。", "校验失败", MessageBoxButtons.OK, MessageBoxIcon.Warning); + txtWeightDown.Focus(); + txtWeightDown.SelectAll(); + return; + } + + if (string.IsNullOrWhiteSpace(upText) || + !double.TryParse(upText.Replace(',', '.').Replace('。', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var up) || up <= 0) + { + MessageBox.Show("请输入有效的上限(g),必须为正数。", "校验失败", MessageBoxButtons.OK, MessageBoxIcon.Warning); + txtWeightUp.Focus(); + txtWeightUp.SelectAll(); + return; + } + + if (down >= up) + { + MessageBox.Show("下限(g)必须小于上限(g)。", "校验失败", MessageBoxButtons.OK, MessageBoxIcon.Warning); + txtWeightDown.Focus(); + txtWeightDown.SelectAll(); + return; + } + + var downStr = down.ToString("0.###", CultureInfo.InvariantCulture); + var upStr = up.ToString("0.###", CultureInfo.InvariantCulture); + + ConfigHelper.SetValue("WeightDown", downStr); + ConfigHelper.SetValue("WeightUp", upStr); + + WeightDown = down; + WeightUp = up; + + txtWeightDown.Text = downStr; + txtWeightUp.Text = upStr; + + logger.Info($"称重配置已更新:WeightDown={downStr}g, WeightUp={upStr}g"); + MessageBox.Show("配置已保存并立即生效。", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + logger.Error(ex, "保存称重配置失败"); + MessageBox.Show($"保存配置失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } } } diff --git a/FATrace.Model/RawProUse.cs b/FATrace.Model/RawProUse.cs index 3a9cc86..8d390c9 100644 --- a/FATrace.Model/RawProUse.cs +++ b/FATrace.Model/RawProUse.cs @@ -11,6 +11,7 @@ namespace FATrace.Model /// 原料生产 使用信息 /// [Table(Name = "RawProUse")] + [Index("idx_RawProUse_WeightTime", "WeightTime")] public class RawProUse { /// diff --git a/FATrace.WPLApp/Services/DataServices.cs b/FATrace.WPLApp/Services/DataServices.cs index 8017f2c..2f2765b 100644 --- a/FATrace.WPLApp/Services/DataServices.cs +++ b/FATrace.WPLApp/Services/DataServices.cs @@ -50,13 +50,40 @@ namespace FATrace.WPLApp.Services private void LineSglModel_BoxSprayCodeReqHandle(object? sender, string e) { //首先复位PLC信号 - KeyencePlcMcNet!.Write("D1100", (Int16)0); + var SetValueResult = KeyencePlcMcNet!.Write("D1100", (Int16)0); + if (!SetValueResult.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("外箱喷码-复位PLC信号失败-执行两次写入0"); + KeyencePlcMcNet!.Write("D1100", (Int16)0); + KeyencePlcMcNet!.Write("D1100", (Int16)0); + } //获取箱子喷码的数据+A var ReqData = FreeSql.Select() - .OrderBy(a => a.Id) + .OrderByDescending(a => a.Id) .Limit(1) .ToList(); + + //无数据再重试一次 + if (ReqData.Count <= 0) + { + try + { + Thread.Sleep(50); + } + catch + { + } + + ReqData = FreeSql.Select() + .OrderByDescending(a => a.Id) + .Limit(1) + .ToList(); + + LogService.Warn("外箱喷码-不存在请求的数据-重试一次"); + } + if (ReqData.Count > 0) { var CodeItem = ReqData.FirstOrDefault(); @@ -65,12 +92,15 @@ namespace FATrace.WPLApp.Services var BoxSprayCodeRev = RevData(BoxSprayCodeSource); BoxSprayCode = BoxSprayCodeSource; - KeyencePlcMcNet.Write("D1150", BoxSprayCodeRev); - + var Result = KeyencePlcMcNet.Write("D1150", BoxSprayCodeRev); + if (!Result.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("外箱喷码-写入条码 D1150 PLC信号失败-执行两次写入条码"); + KeyencePlcMcNet.Write("D1150", BoxSprayCodeRev); + } Console.WriteLine($"外箱喷码:{BoxSprayCodeSource}-发送OK"); - //这里需要删除数据吗?还是等扫码后删除,会不会过来新的箱子 - } else { @@ -78,13 +108,22 @@ namespace FATrace.WPLApp.Services KeyencePlcMcNet.Write("D1102", (Int16)1); Console.WriteLine($"外箱喷码:不存在请求的数据"); AddAlarm("外箱喷码", "不存在请求的数据"); + LogService.Warn("外箱喷码-不存在请求的数据"); } Task.Run(async () => { await Task.Delay(1000).ConfigureAwait(false); - KeyencePlcMcNet!.Write("D1102", (Int16)0); + var Data = KeyencePlcMcNet!.Write("D1102", (Int16)0); + if (!Data.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("外箱喷码-复位D1102PLC信号失败-执行两次写入0"); + KeyencePlcMcNet!.Write("D1102", (Int16)0); + KeyencePlcMcNet!.Write("D1102", (Int16)0); + } + //KeyencePlcMcNet.Write("D1150", new Int16[30]); }); @@ -99,7 +138,14 @@ namespace FATrace.WPLApp.Services private void LineSglModel_BoxScanCodeReqHandle(object? sender, string e) { //首先复位PLC信号 - KeyencePlcMcNet!.Write("D1200", (Int16)0); + var SetValueResult = KeyencePlcMcNet!.Write("D1200", (Int16)0); + if (!SetValueResult.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("外箱扫描码请求-复位PLC信号失败-执行两次写入0"); + KeyencePlcMcNet!.Write("D1200", (Int16)0); + KeyencePlcMcNet!.Write("D1200", (Int16)0); + } string BoxScanCode = string.Empty; BoxScanCode = this.BoxScanCode; @@ -111,7 +157,14 @@ namespace FATrace.WPLApp.Services if (IsExist.Count() > 0) { //存在条码数据 OK,返回PLC结果 - KeyencePlcMcNet!.Write("D1210", (Int16)1); + var DataResult = KeyencePlcMcNet!.Write("D1210", (Int16)1); + if (!DataResult.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("外箱扫描码请求-置位D1210PLC信号失败-执行两次写入1"); + KeyencePlcMcNet!.Write("D1210", (Int16)1); + KeyencePlcMcNet!.Write("D1210", (Int16)1); + } Console.WriteLine($"外箱扫描码:{BoxScanCode}-存在找到"); // 加入队列 @@ -181,8 +234,15 @@ namespace FATrace.WPLApp.Services Task.Run(async () => { - await Task.Delay(1000).ConfigureAwait(false); - KeyencePlcMcNet!.Write("D1210", (Int16)0); + await Task.Delay(1200).ConfigureAwait(false); + var DataResult = KeyencePlcMcNet!.Write("D1210", (Int16)0); + if (!DataResult.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("外箱扫描码请求-复位D1210PLC信号失败-执行两次写入0"); + KeyencePlcMcNet!.Write("D1210", (Int16)0); + KeyencePlcMcNet!.Write("D1210", (Int16)0); + } KeyencePlcMcNet.Write("D1250", new Int16[30]); }); @@ -198,7 +258,14 @@ namespace FATrace.WPLApp.Services private void LineSglModel_WeightScanCodeHandle(object? sender, string e) { //首先复位PLC信号 - KeyencePlcMcNet!.Write("D1000", (Int16)0); + var SetValueResult = KeyencePlcMcNet!.Write("D1000", (Int16)0); + if (!SetValueResult.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("称重扫描码-复位PLC信号失败-执行两次写入0"); + KeyencePlcMcNet!.Write("D1000", (Int16)0); + KeyencePlcMcNet!.Write("D1000", (Int16)0); + } if (!string.IsNullOrEmpty(WeightScanCode)) { @@ -206,24 +273,47 @@ namespace FATrace.WPLApp.Services if (IsExist.Count() > 0) { //存在条码数据 OK,返回PLC结果 - KeyencePlcMcNet!.Write("D1010", (Int16)1); + var SetValueResult1 = KeyencePlcMcNet!.Write("D1010", (Int16)1); + if (!SetValueResult1.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("称重扫描码-置位数据D1010 PLC信号失败-执行两次写入1"); + KeyencePlcMcNet!.Write("D1010", (Int16)1); + KeyencePlcMcNet!.Write("D1010", (Int16)1); + } Console.WriteLine($"称重扫描码:{WeightScanCode}"); //// 加入队列 //EnqueueMessage(WeightScanCode); LogService.Info($"称重扫描码:{WeightScanCode}"); - var TempData = FreeSql.Insert(new LineTempCode() + try { - Code = WeightScanCode - }).ExecuteAffrows(); + var delAff = FreeSql.Delete() + .Where(p => p.Id > 0) + .ExecuteAffrows(); + + var insAff = FreeSql.Insert(new LineTempCode() + { + Code = WeightScanCode + }).ExecuteAffrows(); + + if (insAff <= 0) + { + LogService.Warn($"称重扫描码:{WeightScanCode} 写入临时表 LineTempCode 失败(affrows={insAff}),delAff={delAff}"); + } + } + catch (Exception ex) + { + LogService.Error($"称重扫描码:{WeightScanCode} 写入临时表 LineTempCode 异常: {ex}"); + } try { EventAggregator?.GetEvent()?.Publish(true); } catch { - + } var Result = FreeSql.Update() @@ -254,8 +344,16 @@ namespace FATrace.WPLApp.Services Task.Run(async () => { - await Task.Delay(1000).ConfigureAwait(false); - KeyencePlcMcNet!.Write("D1010", (Int16)0); + await Task.Delay(1200).ConfigureAwait(false); + + //KeyencePlcMcNet!.Write("D1010", (Int16)0); + var SetValueResult2 = KeyencePlcMcNet!.Write("D1010", (Int16)0); + if (!SetValueResult2.IsSuccess) + { + //写入失败,重新写入 + LogService.Warn("称重扫描码-复位数据D1010 PLC信号失败-执行两次写入0"); + KeyencePlcMcNet!.Write("D1010", (Int16)0); + } KeyencePlcMcNet.Write("D1050", new Int16[30]); }); @@ -323,7 +421,6 @@ namespace FATrace.WPLApp.Services } - // 扫描控制 private CancellationTokenSource? _plcScanCts; private Task? _plcScanTask; @@ -331,10 +428,6 @@ namespace FATrace.WPLApp.Services public bool IsScanning => _isScanning; private bool _disposed = false; - /// - /// 简单字符串队列(FIFO) - /// - private readonly ConcurrentQueue _messageQueue = new(); /// /// 产线信号模型 @@ -366,6 +459,7 @@ namespace FATrace.WPLApp.Services if (connect.IsSuccess)//初始连接状态的显示判断 { Console.WriteLine($"PLC-连接 OK"); + LogService.Error($"PLC-连接 OK"); PlcConnected = true; try { SysRunService.PlcLinkState = true; SysRunService.SysRunState.ComState = 1; SysRunService.SysRunState.ComMsg = "正常"; } catch { } } @@ -400,7 +494,31 @@ namespace FATrace.WPLApp.Services var token = _plcScanCts.Token; _isScanning = true; + try { SysRunService.PlcScanState = 1; } catch { } + _plcScanTask = Task.Run(() => PlcScanLoopAsync(period, token), token); + _plcScanTask.ContinueWith(t => + { + try + { + if (t.IsFaulted) + { + try { SysRunService.PlcScanState = 2; } catch { } + try { LogService.Error($"PLC扫描任务异常退出: {t.Exception}"); } catch { } + } + else if (t.IsCanceled) + { + try { SysRunService.PlcScanState = 0; } catch { } + } + else + { + try { SysRunService.PlcScanState = 0; } catch { } + } + } + catch + { + } + }, TaskScheduler.Default); } /// @@ -425,6 +543,8 @@ namespace FATrace.WPLApp.Services _plcScanTask = null; _plcScanCts?.Dispose(); _plcScanCts = null; + + try { SysRunService.PlcScanState = 0; } catch { } } } @@ -513,13 +633,12 @@ namespace FATrace.WPLApp.Services } } - catch (OperationCanceledException) - { - break; - } catch (Exception ex) { - LogService.Error($"PLC 扫描异常: {ex}"); + LogService.Error($"PLC 扫描异常 Exception: {ex.ToString()}"); + + // 这里属于循环内部异常:循环仍会继续; + // 但若后续由于未捕获异常导致扫描任务退出,StartPlcScan 的 ContinueWith 也会做最终状态处理。 } finally { @@ -527,14 +646,23 @@ namespace FATrace.WPLApp.Services { await Task.Delay(period, token).ConfigureAwait(false); } - catch (OperationCanceledException) + catch (OperationCanceledException ex) { + // 正常停止扫描时会触发取消,这里不应记录为错误。 // 不允许从 finally 中 break/return, // 这里吞掉异常,循环将在下一次 while 判断时依据 token 自动退出 } } } _isScanning = false; + + // 退出循环:如果是正常取消,则 StopPlcScanAsync 会把状态置为停止; + // 若是外部未走 StopPlcScanAsync,而 token 已取消,也归为停止。 + try + { + if (token.IsCancellationRequested) SysRunService.PlcScanState = 0; + } + catch { } } /// diff --git a/FATrace.WPLApp/Services/LogService.cs b/FATrace.WPLApp/Services/LogService.cs index 462347d..f33bf97 100644 --- a/FATrace.WPLApp/Services/LogService.cs +++ b/FATrace.WPLApp/Services/LogService.cs @@ -14,6 +14,14 @@ namespace FATrace.WPLApp.Services { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); // 初始化日志类 + private static bool IsQueryNoise(string msg) + { + if (string.IsNullOrWhiteSpace(msg)) return false; + return msg.IndexOf("查询开始", StringComparison.OrdinalIgnoreCase) >= 0 + || msg.IndexOf("查询完成", StringComparison.OrdinalIgnoreCase) >= 0 + || msg.IndexOf("记录数", StringComparison.OrdinalIgnoreCase) >= 0; + } + /// /// 调试日志 /// @@ -29,8 +37,16 @@ namespace FATrace.WPLApp.Services /// 适用大部分场景 /// 1.记录日志文件 /// - public void Info(string msg) => Logger.Info(msg); - public void Info(string msg, Exception ex) => Logger.Info(ex, msg); + public void Info(string msg) + { + if (IsQueryNoise(msg)) return; + Logger.Info(msg); + } + public void Info(string msg, Exception ex) + { + if (IsQueryNoise(msg)) return; + Logger.Info(ex, msg); + } /// /// 错误日志 diff --git a/FATrace.WPLApp/Services/SysRunService.cs b/FATrace.WPLApp/Services/SysRunService.cs index 509cbc1..39332d8 100644 --- a/FATrace.WPLApp/Services/SysRunService.cs +++ b/FATrace.WPLApp/Services/SysRunService.cs @@ -68,6 +68,46 @@ namespace FATrace.WPLApp.Services set { _PlcLinkState = value;RaisePropertyChanged(); } } + private int _PlcScanState = 0; + /// + /// PLC扫描循环状态 + /// 0=已停止,1=运行中,2=异常退出 + /// + public int PlcScanState + { + get { return _PlcScanState; } + set + { + if (_PlcScanState != value) + { + _PlcScanState = value; + switch (value) + { + case 1: + PlcScanMsg = "扫描运行"; + break; + case 2: + PlcScanMsg = "扫描异常"; + break; + default: + PlcScanMsg = "扫描停止"; + break; + } + RaisePropertyChanged(); + } + } + } + + private string? _PlcScanMsg = "扫描停止"; + /// + /// PLC扫描循环状态消息 + /// + public string? PlcScanMsg + { + get { return _PlcScanMsg; } + set { _PlcScanMsg = value; RaisePropertyChanged(); } + } + private string? _CurUser; /// diff --git a/FATrace.WPLApp/ViewModels/DashboardViewModel.cs b/FATrace.WPLApp/ViewModels/DashboardViewModel.cs index e6ede0d..4e96aae 100644 --- a/FATrace.WPLApp/ViewModels/DashboardViewModel.cs +++ b/FATrace.WPLApp/ViewModels/DashboardViewModel.cs @@ -41,7 +41,6 @@ namespace FATrace.WPLApp.ViewModels _ea = ea; LiveMessages = new ObservableCollection(); - LineTempCodes = new ObservableCollection(); RefreshCommand = new DelegateCommand(async () => await RefreshStatsAsync()); ClearLogsCommand = new DelegateCommand(() => LiveMessages.Clear()); @@ -168,7 +167,6 @@ namespace FATrace.WPLApp.ViewModels try { await RefreshStatsAsync(); - await RefreshLineTempCodesAsync(); } catch (Exception ex) { @@ -206,11 +204,6 @@ namespace FATrace.WPLApp.ViewModels public bool PlcConnected { get => _plcConnected; set { _plcConnected = value; RaisePropertyChanged(); } } public ObservableCollection LiveMessages { get; } - - /// - /// 产线临时条码队列(内包扫码入队,外箱扫码确认后出队) - /// - public ObservableCollection LineTempCodes { get; } #endregion #region Commands @@ -285,52 +278,6 @@ namespace FATrace.WPLApp.ViewModels } } - /// - /// 从数据库刷新产线临时队列(LineTempCode 表)并同步到 UI。 - /// - private async Task RefreshLineTempCodesAsync() - { - try - { - var list = await Task.Run(() => - { - return _fsql.Select() - .OrderBy(a => a.Id) - .Limit(200) - .ToList(); - }); - - void apply() - { - LineTempCodes.Clear(); - foreach (var item in list) - { - LineTempCodes.Add(item); - } - } - - var dispatcher = Application.Current?.Dispatcher; - if (dispatcher == null) - { - apply(); - return; - } - - if (dispatcher.CheckAccess()) - { - apply(); - } - else - { - await dispatcher.InvokeAsync(apply).Task.ConfigureAwait(false); - } - } - catch (Exception ex) - { - _log.Error($"刷新 LineTempCode 队列失败: {ex}"); - } - } - public override async void OnNavigatedTo(Prism.Regions.NavigationContext navigationContext) { try @@ -351,7 +298,6 @@ namespace FATrace.WPLApp.ViewModels LatestWeightScanCode = _data.WeightScanCode; LatestBoxScanCode = _data.BoxScanCode; LatestBoxSprayCode = _data.BoxSprayCode; - await RefreshLineTempCodesAsync(); TryHookConsole(); } } diff --git a/FATrace.WPLApp/Views/DashboardView.xaml b/FATrace.WPLApp/Views/DashboardView.xaml index ffa48ba..de90d6f 100644 --- a/FATrace.WPLApp/Views/DashboardView.xaml +++ b/FATrace.WPLApp/Views/DashboardView.xaml @@ -7,7 +7,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:prism="http://prismlibrary.com/" d:DesignHeight="720" - d:DesignWidth="1280" + d:DesignWidth="1580" prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d"> @@ -227,92 +227,100 @@ - - - + + + + + + + + + + - + + + + + + + + + + + + 常见检查事项: + + 1.检查产线电气柜上电 + 2.检查软件是否打开 + 3.检查软件底部的状态 + 4.检查喷码器状态 + + + + + diff --git a/FATrace.WPLApp/Views/FootView.xaml b/FATrace.WPLApp/Views/FootView.xaml index 94df29a..5d19a46 100644 --- a/FATrace.WPLApp/Views/FootView.xaml +++ b/FATrace.WPLApp/Views/FootView.xaml @@ -13,7 +13,7 @@ - + @@ -137,5 +137,43 @@ + + + + + + + + + + + + + + + + diff --git a/FATrace.WPLApp/Views/RawProInputView.xaml b/FATrace.WPLApp/Views/RawProInputView.xaml index 42afe73..2fb3d41 100644 --- a/FATrace.WPLApp/Views/RawProInputView.xaml +++ b/FATrace.WPLApp/Views/RawProInputView.xaml @@ -207,19 +207,53 @@ + Header="保质期(月)" /> - + + + + + + + + + + + + + + + + + + + +