quanzhou
2025-09-11 31de09d1ba504cb036ae29a98a9efbb0c2d61914
增加扫码上传打印追溯条码的界面以及对mes的开关添加了日志
6个文件已添加
4个文件已修改
1021 ■■■■■ 已修改文件
src/Bro.M141.Process/M141Process.cs 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/M141Process_Mysql.cs 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/UI/DataPrinter.Designer.cs 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/UI/DataPrinter.cs 262 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/UI/DataPrinter.resx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/UI/Frm_Login.Designer.cs 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/UI/Frm_Login.cs 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/UI/Frm_Login.resx 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/UI/UIPrinter.cs 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141_AOI1.Process/AOI1Process.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.M141.Process/M141Process.cs
@@ -145,6 +145,10 @@
                mqtt = new RabbitMQHelper(M141Config.zIP, M141Config.zport, M141Config.zuser, M141Config.zpassword);
                mqtt.Connect(M141Config.MESchannel);
            }
            else
            {
                LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"已关闭上传mes");
            }
            InitialContinuousNGAlarm();
        }
@@ -1615,7 +1619,10 @@
                            }
                        }
                        else
                        {
                            LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"已关闭mes连接或者数据上传接口");
                        }
                    }
                    //ReplyPlcData(positionName, config.TriggerValue);
@@ -1936,8 +1943,8 @@
                {
                    DisableECI = true,//设置内容编码
                    CharacterSet = "UTF-8",  //设置二维码的宽度和高度
                    Width = 123,
                    Height = 123,
                    Width = 60,
                    Height = 60,
                    Margin = 1//设置二维码的边距,单位不是固定像素
                };
src/Bro.M141.Process/M141Process_Mysql.cs
@@ -406,6 +406,38 @@
            return "NoRead";
        }
        public List<ProductModel> SNGetProductList(string sn,string device)
        {
            try
            {
                string mysqlstr = $"select data from forall where sn='{sn}' and device='{device}'";
                var dt = selectdt(mysqlstr, connStrAll);
                if (dt == null)
                {
                    return null;
                }
                else
                {
                    List<ProductModel> plist = new List<ProductModel>();
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        string strjson = dt.Rows[i][0].ToString();
                        strjson = strjson.Replace(@"\", @"\\");
                        ProductModel p = JsonConvert.DeserializeObject<ProductModel>(strjson, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });
                        //JsonConvert.DeserializeObject<IProcessConfig>(_configBackupStr, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });
                        plist.Add(p);
                    }
                    return plist;
                }
            }
            catch (Exception e)
            {
                CommonLogger.LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"数据库forall数据异常 {e.ToString()}");
            }
            return null;
        }
        public List<ProductModel> GetProductList(string plcnum)
        {
            try
src/Bro.M141.Process/UI/DataPrinter.Designer.cs
New file
@@ -0,0 +1,267 @@
namespace Bro.M141.Process.UI
{
    partial class DataPrinter
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle();
            DataGridViewCellStyle dataGridViewCellStyle2 = new DataGridViewCellStyle();
            DataGridViewCellStyle dataGridViewCellStyle3 = new DataGridViewCellStyle();
            DataGridViewCellStyle dataGridViewCellStyle4 = new DataGridViewCellStyle();
            Codesdataview = new Sunny.UI.UIDataGridView();
            Column5 = new DataGridViewTextBoxColumn();
            Column6 = new DataGridViewTextBoxColumn();
            uiButton1 = new Sunny.UI.UIButton();
            uiLabel1 = new Sunny.UI.UILabel();
            Data_Textbox = new Sunny.UI.UITextBox();
            button1 = new Button();
            uiLabel2 = new Sunny.UI.UILabel();
            uiLabel3 = new Sunny.UI.UILabel();
            uiLabel4 = new Sunny.UI.UILabel();
            uiCheckBox2 = new Sunny.UI.UICheckBox();
            uiCheckBox1 = new Sunny.UI.UICheckBox();
            uiCheckBox3 = new Sunny.UI.UICheckBox();
            ((System.ComponentModel.ISupportInitialize)Codesdataview).BeginInit();
            SuspendLayout();
            //
            // Codesdataview
            //
            Codesdataview.AllowUserToAddRows = false;
            Codesdataview.AllowUserToDeleteRows = false;
            dataGridViewCellStyle1.BackColor = Color.FromArgb(235, 243, 255);
            Codesdataview.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;
            Codesdataview.BackgroundColor = Color.White;
            Codesdataview.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
            dataGridViewCellStyle2.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridViewCellStyle2.BackColor = Color.FromArgb(80, 160, 255);
            dataGridViewCellStyle2.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            dataGridViewCellStyle2.ForeColor = Color.White;
            dataGridViewCellStyle2.SelectionBackColor = SystemColors.Highlight;
            dataGridViewCellStyle2.SelectionForeColor = SystemColors.HighlightText;
            dataGridViewCellStyle2.WrapMode = DataGridViewTriState.True;
            Codesdataview.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle2;
            Codesdataview.ColumnHeadersHeight = 32;
            Codesdataview.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            Codesdataview.Columns.AddRange(new DataGridViewColumn[] { Column5, Column6 });
            Codesdataview.EnableHeadersVisualStyles = false;
            Codesdataview.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            Codesdataview.GridColor = Color.FromArgb(80, 160, 255);
            Codesdataview.Location = new Point(3, 142);
            Codesdataview.Name = "Codesdataview";
            Codesdataview.ReadOnly = true;
            dataGridViewCellStyle3.Alignment = DataGridViewContentAlignment.MiddleLeft;
            dataGridViewCellStyle3.BackColor = Color.FromArgb(235, 243, 255);
            dataGridViewCellStyle3.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            dataGridViewCellStyle3.ForeColor = Color.FromArgb(48, 48, 48);
            dataGridViewCellStyle3.SelectionBackColor = Color.FromArgb(80, 160, 255);
            dataGridViewCellStyle3.SelectionForeColor = Color.White;
            dataGridViewCellStyle3.WrapMode = DataGridViewTriState.True;
            Codesdataview.RowHeadersDefaultCellStyle = dataGridViewCellStyle3;
            Codesdataview.RowHeadersWidth = 51;
            Codesdataview.RowHeight = 25;
            dataGridViewCellStyle4.BackColor = Color.White;
            Codesdataview.RowsDefaultCellStyle = dataGridViewCellStyle4;
            Codesdataview.RowTemplate.Height = 25;
            Codesdataview.SelectedIndex = -1;
            Codesdataview.ShowGridLine = true;
            Codesdataview.Size = new Size(1146, 433);
            Codesdataview.TabIndex = 5;
            //
            // Column5
            //
            Column5.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            Column5.DataPropertyName = "code";
            Column5.HeaderText = "产品二维码";
            Column5.MinimumWidth = 6;
            Column5.Name = "Column5";
            Column5.ReadOnly = true;
            //
            // Column6
            //
            Column6.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            Column6.DataPropertyName = "reasult";
            Column6.HeaderText = "数据";
            Column6.MinimumWidth = 6;
            Column6.Name = "Column6";
            Column6.ReadOnly = true;
            //
            // uiButton1
            //
            uiButton1.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiButton1.IsScaled = false;
            uiButton1.Location = new Point(928, 28);
            uiButton1.MinimumSize = new Size(1, 1);
            uiButton1.Name = "uiButton1";
            uiButton1.Size = new Size(150, 52);
            uiButton1.TabIndex = 8;
            uiButton1.Text = "用户解锁";
            uiButton1.Click += uiButton1_Click;
            //
            // uiLabel1
            //
            uiLabel1.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiLabel1.Location = new Point(15, 23);
            uiLabel1.Name = "uiLabel1";
            uiLabel1.Size = new Size(153, 34);
            uiLabel1.TabIndex = 9;
            uiLabel1.Text = "产品条码:";
            uiLabel1.TextAlign = ContentAlignment.MiddleLeft;
            //
            // Data_Textbox
            //
            Data_Textbox.ButtonSymbol = 61761;
            Data_Textbox.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            Data_Textbox.IsScaled = false;
            Data_Textbox.Location = new Point(144, 23);
            Data_Textbox.Margin = new Padding(4, 5, 4, 5);
            Data_Textbox.Maximum = 2147483647D;
            Data_Textbox.Minimum = -2147483648D;
            Data_Textbox.MinimumSize = new Size(1, 1);
            Data_Textbox.Name = "Data_Textbox";
            Data_Textbox.Size = new Size(380, 39);
            Data_Textbox.TabIndex = 10;
            Data_Textbox.TextAlignment = ContentAlignment.MiddleLeft;
            Data_Textbox.KeyPress += Data_Textbox_KeyPress;
            //
            // button1
            //
            button1.Location = new Point(531, 28);
            button1.Name = "button1";
            button1.Size = new Size(112, 34);
            button1.TabIndex = 11;
            button1.Text = "查询";
            button1.UseVisualStyleBackColor = true;
            //
            // uiLabel2
            //
            uiLabel2.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiLabel2.Location = new Point(663, 28);
            uiLabel2.Name = "uiLabel2";
            uiLabel2.Size = new Size(68, 34);
            uiLabel2.TabIndex = 12;
            uiLabel2.Text = "结果";
            uiLabel2.TextAlign = ContentAlignment.MiddleLeft;
            //
            // uiLabel3
            //
            uiLabel3.BackColor = SystemColors.Control;
            uiLabel3.Font = new Font("微软雅黑", 22F, FontStyle.Regular, GraphicsUnit.Point);
            uiLabel3.Location = new Point(737, 12);
            uiLabel3.Name = "uiLabel3";
            uiLabel3.Size = new Size(100, 80);
            uiLabel3.TabIndex = 13;
            uiLabel3.Text = "OK";
            uiLabel3.TextAlign = ContentAlignment.MiddleLeft;
            //
            // uiLabel4
            //
            uiLabel4.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiLabel4.Location = new Point(596, 92);
            uiLabel4.Name = "uiLabel4";
            uiLabel4.Size = new Size(230, 33);
            uiLabel4.TabIndex = 14;
            uiLabel4.Text = "结果详细";
            uiLabel4.TextAlign = ContentAlignment.MiddleLeft;
            //
            // uiCheckBox2
            //
            uiCheckBox2.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiCheckBox2.IsScaled = false;
            uiCheckBox2.Location = new Point(134, 92);
            uiCheckBox2.MinimumSize = new Size(1, 1);
            uiCheckBox2.Name = "uiCheckBox2";
            uiCheckBox2.Padding = new Padding(22, 0, 0, 0);
            uiCheckBox2.Size = new Size(187, 44);
            uiCheckBox2.TabIndex = 15;
            uiCheckBox2.Text = "查询AOI检测";
            uiCheckBox2.CheckedChanged += uiCheckBox2_CheckedChanged;
            //
            // uiCheckBox1
            //
            uiCheckBox1.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiCheckBox1.IsScaled = false;
            uiCheckBox1.Location = new Point(15, 92);
            uiCheckBox1.MinimumSize = new Size(1, 1);
            uiCheckBox1.Name = "uiCheckBox1";
            uiCheckBox1.Padding = new Padding(22, 0, 0, 0);
            uiCheckBox1.Size = new Size(113, 44);
            uiCheckBox1.TabIndex = 16;
            uiCheckBox1.Text = "仅扫码";
            uiCheckBox1.CheckedChanged += uiCheckBox1_CheckedChanged;
            //
            // uiCheckBox3
            //
            uiCheckBox3.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiCheckBox3.IsScaled = false;
            uiCheckBox3.Location = new Point(327, 92);
            uiCheckBox3.MinimumSize = new Size(1, 1);
            uiCheckBox3.Name = "uiCheckBox3";
            uiCheckBox3.Padding = new Padding(22, 0, 0, 0);
            uiCheckBox3.Size = new Size(187, 44);
            uiCheckBox3.TabIndex = 17;
            uiCheckBox3.Text = "上传mes";
            //
            // DataPrinter
            //
            AutoScaleDimensions = new SizeF(6F, 13F);
            AutoScaleMode = AutoScaleMode.Font;
            Controls.Add(uiCheckBox3);
            Controls.Add(uiCheckBox1);
            Controls.Add(uiCheckBox2);
            Controls.Add(uiLabel4);
            Controls.Add(uiLabel3);
            Controls.Add(uiLabel2);
            Controls.Add(button1);
            Controls.Add(Data_Textbox);
            Controls.Add(uiLabel1);
            Controls.Add(uiButton1);
            Controls.Add(Codesdataview);
            Margin = new Padding(1, 2, 1, 2);
            Name = "DataPrinter";
            Size = new Size(1152, 579);
            Load += DataPrinter_Load;
            ((System.ComponentModel.ISupportInitialize)Codesdataview).EndInit();
            ResumeLayout(false);
        }
        #endregion
        private Sunny.UI.UIDataGridView Codesdataview;
        private Sunny.UI.UIButton uiButton1;
        private Sunny.UI.UILabel uiLabel1;
        public Sunny.UI.UITextBox Data_Textbox;
        private Button button1;
        private Sunny.UI.UILabel uiLabel2;
        private Sunny.UI.UILabel uiLabel3;
        private Sunny.UI.UILabel uiLabel4;
        private Sunny.UI.UICheckBox uiCheckBox2;
        private Sunny.UI.UICheckBox uiCheckBox1;
        private DataGridViewTextBoxColumn Column5;
        private DataGridViewTextBoxColumn Column6;
        private Sunny.UI.UICheckBox uiCheckBox3;
    }
}
src/Bro.M141.Process/UI/DataPrinter.cs
New file
@@ -0,0 +1,262 @@
using Bro.Common.Helper;
using Bro.M135.Common;
using Bro.UI.Model.Winform;
using Newtonsoft.Json;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Bro.M141.Process.UI
{
    [MenuNode("扫码界面", "扫码界面", 2, EnumHelper.TopMenu.SystemInfo, MenuNodeType.Form)]
    public partial class DataPrinter : MenuFormBase
    {
        public DataPrinter()
        {
            InitializeComponent();
        }
        private static DataPrinter _instance;
        public static DataPrinter GetInstance()
        {
            if (_instance == null || _instance.IsDisposed)
            {
                _instance = new DataPrinter();
            }
            return _instance;
        }
        M141Config Config141 => Process.IConfig as M141Config;
        M141Process Process141 => Process as M141Process;
        M141Process_Mysql mysqlhelper = new M141Process_Mysql();
        public override void OnProcessUpdated()
        {
            base.OnProcessUpdated();
            Process141.RerefreshBasketcodeUI += RerefreshUI;
            RerefreshUI();
        }
        private void RerefreshUI()
        {
            mysqlhelper.IniDBIP(Config141.IPforall);
        }
        public class codedata
        {
            public string code { get; set; }
            public string reasult { get; set; }
        }
        private void DataPrinter_Load(object sender, EventArgs e)
        {
            Data_Textbox.Focus();
        }
        private void Data_Textbox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
            {
                // 如果是回车键
                e.Handled = true;
                string barcode = Data_Textbox.Text;
                if (!string.IsNullOrEmpty(barcode))
                {
                    // 将条码全部选中,下一次扫码的时候,旧条码就会被新条码覆盖
                    Data_Textbox.SelectAll();
                    // 处理条码
                    // ProcessBarcode(barcode);
                    DatatoGridView(barcode);
                    Data_Textbox.Focus();
                }
            }
        }
        List<codedata> codes = new List<codedata>();
        public bool ISOK = true;
        private void DatatoGridView(string ID)
        {
            if (!ISOK)
            {
                MessageBox.Show("前一个条码为NG,需要解锁");
                return;
            }
            if (uiCheckBox1.Checked == true)
            {
                uiLabel3.Text = "OK";
                uiLabel3.ForeColor = Color.Green;
                codes.Add(new codedata()
                {
                    code = ID,
                    reasult = "OK",
                });
                //上传mes
            }
            else
            {
                var plist = mysqlhelper.SNGetProductList(ID, "S2");
                var plist1 = mysqlhelper.SNGetProductList(ID, "S3");
                var plist2 = mysqlhelper.SNGetProductList(ID, "S4");
                var plist3 = mysqlhelper.SNGetProductList(ID, "S5");
                if (plist != null && plist1 != null && plist2 != null && plist3 != null)//判断产品是否存在
                {
                    if (plist.Count != 0 && plist1.Count != 0 && plist2.Count != 0 && plist3.Count != 0)
                    {
                        if (plist[0].Result == "OK" && plist1[0].Result == "OK" && plist2[0].Result == "OK" && plist3[0].Result == "OK")
                        {
                            uiLabel3.Text = "OK";
                            uiLabel3.ForeColor = Color.Green;
                            uiLabel4.Text = "产品检测为OK";
                            //上传mes
                            ProductModel newp = new ProductModel();
                            newp.SEQUENCE = plist[0].SEQUENCE;
                            newp.PID = plist[0].PID;
                            newp.Zword = plist[0].Zword;
                            newp.BasketCode = plist[0].BasketCode;
                            newp.Result = "OK";
                            newp.SN = plist[0].SN;
                            if (uiCheckBox3.Checked)
                            {
                                if (Config141.numpro >= 50)
                                {
                                    Config141.numpro = 0;
                                }
                                Config141.numpro++;
                                var Msgreceice = Task.Run(() => Process141.mqtt.MESForProduceAsync(newp, Config141.mesnum2.ToString(), Config141.numpro)).Result;
                                Config141.mesnum2++;
                                if (Msgreceice != null)
                                {
                                    var obj = JsonConvert.DeserializeObject<AutoLineMacBarcodeQueueBak>(Msgreceice);
                                    if (obj.zstatus == "200")
                                    {
                                        LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{newp.PID}数据上传MES成功  {Msgreceice}");
                                        if (Config141.Isprint && !string.IsNullOrEmpty(obj.tary_label))
                                        {
                                            Process141.StartPrint(obj.tary_label);
                                        }
                                    }
                                    else
                                    {
                                        LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"产品{newp.PID}数据上传MES失败  {Msgreceice}");
                                    }
                                }
                            }
                        }
                        else
                        {
                            uiLabel3.Text = "NG";
                            uiLabel3.ForeColor = Color.Red;
                             ISOK = false;
                            if (plist[0]?.Result == "OK" && plist2[0]?.Result == "OK")
                            {
                                uiLabel4.Text = "缺陷为外观NG";
                            }
                            else
                            {
                                uiLabel4.Text = "缺陷为AOI尺寸NG";
                            }
                        }
                        codes.Add(new codedata()
                        {
                            code = ID,
                            reasult = uiLabel4.Text,
                        });
                    }
                    else
                    {
                        uiLabel3.Text = "NG";
                        uiLabel3.ForeColor = Color.Red;
                        ISOK = false;
                        uiLabel4.Text = "产品未查询到结果";
                        codes.Add(new codedata
                        {
                            code = ID,
                            reasult = "无数据",
                        });
                    }
                }
                else
                {
                    uiLabel3.Text = "NG";
                    uiLabel3.ForeColor = Color.Red;
                    ISOK = false;
                    uiLabel4.Text = "产品未查询到结果";
                    codes.Add(new codedata
                    {
                        code = ID,
                        reasult = "无数据",
                    });
                }
            }
            Data_Textbox.Text = "";
            Data_Textbox.Focus();
            var bindingSource = new BindingSource { DataSource = codes };
            Codesdataview.DataSource = bindingSource;
            Codesdataview.Refresh();
        }
        private void uiCheckBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (uiCheckBox1.Checked)
            {
                uiCheckBox2.Checked = false;
            }
        }
        private void uiCheckBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (uiCheckBox2.Checked)
            {
                uiCheckBox1.Checked = false;
            }
        }
        private void uiButton1_Click(object sender, EventArgs e)
        {
            Frm_Login.GetInstance().changeBool += new Frm_Login.ChangeBoolHander(change_bool);
            Frm_Login.GetInstance().ShowDialog();
        }
        public void change_bool(bool islogin)
        {
            ISOK = islogin;
        }
    }
}
src/Bro.M141.Process/UI/DataPrinter.resx
New file
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!--
    Microsoft ResX Schema
    Version 2.0
    The primary goals of this format is to allow a simple XML format
    that is mostly human readable. The generation and parsing of the
    various data types are done through the TypeConverter classes
    associated with the data types.
    Example:
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
    There are any number of "resheader" rows that contain simple
    name/value pairs.
    Each data row contains a name, and value. The row also contains a
    type or mimetype. Type corresponds to a .NET class that support
    text/value conversion through the TypeConverter architecture.
    Classes that don't support this are serialized and stored with the
    mimetype set.
    The mimetype is used for serialized objects, and tells the
    ResXResourceReader how to depersist the object. This is currently not
    extensible. For a given mimetype the value must be set accordingly:
    Note - application/x-microsoft.net.object.binary.base64 is the format
    that the ResXResourceWriter will generate, however the reader can
    read any of the formats listed below.
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.
    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="Column5.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
  <metadata name="Column6.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
</root>
src/Bro.M141.Process/UI/Frm_Login.Designer.cs
New file
@@ -0,0 +1,125 @@
namespace Bro.M141.Process.UI
{
    partial class Frm_Login
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            uiButton1 = new Sunny.UI.UIButton();
            uiTextBox2 = new Sunny.UI.UITextBox();
            uiLabel2 = new Sunny.UI.UILabel();
            uiTextBox1 = new Sunny.UI.UITextBox();
            uiLabel1 = new Sunny.UI.UILabel();
            SuspendLayout();
            //
            // uiButton1
            //
            uiButton1.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiButton1.IsScaled = false;
            uiButton1.Location = new Point(568, 294);
            uiButton1.MinimumSize = new Size(1, 1);
            uiButton1.Name = "uiButton1";
            uiButton1.Size = new Size(150, 52);
            uiButton1.TabIndex = 9;
            uiButton1.Text = "用户登入";
            uiButton1.Click += uiButton1_Click;
            //
            // uiTextBox2
            //
            uiTextBox2.ButtonSymbol = 61761;
            uiTextBox2.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiTextBox2.IsScaled = false;
            uiTextBox2.Location = new Point(214, 212);
            uiTextBox2.Margin = new Padding(4, 5, 4, 5);
            uiTextBox2.Maximum = 2147483647D;
            uiTextBox2.Minimum = -2147483648D;
            uiTextBox2.MinimumSize = new Size(1, 1);
            uiTextBox2.Name = "uiTextBox2";
            uiTextBox2.PasswordChar = '*';
            uiTextBox2.Size = new Size(317, 39);
            uiTextBox2.TabIndex = 8;
            uiTextBox2.TextAlignment = ContentAlignment.MiddleLeft;
            //
            // uiLabel2
            //
            uiLabel2.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiLabel2.Location = new Point(82, 209);
            uiLabel2.Name = "uiLabel2";
            uiLabel2.Size = new Size(150, 34);
            uiLabel2.TabIndex = 7;
            uiLabel2.Text = "用户账号:";
            uiLabel2.TextAlign = ContentAlignment.MiddleLeft;
            //
            // uiTextBox1
            //
            uiTextBox1.ButtonSymbol = 61761;
            uiTextBox1.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiTextBox1.IsScaled = false;
            uiTextBox1.Location = new Point(214, 108);
            uiTextBox1.Margin = new Padding(4, 5, 4, 5);
            uiTextBox1.Maximum = 2147483647D;
            uiTextBox1.Minimum = -2147483648D;
            uiTextBox1.MinimumSize = new Size(1, 1);
            uiTextBox1.Name = "uiTextBox1";
            uiTextBox1.Size = new Size(317, 39);
            uiTextBox1.TabIndex = 6;
            uiTextBox1.Text = "管理员";
            uiTextBox1.TextAlignment = ContentAlignment.MiddleLeft;
            //
            // uiLabel1
            //
            uiLabel1.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point);
            uiLabel1.Location = new Point(82, 105);
            uiLabel1.Name = "uiLabel1";
            uiLabel1.Size = new Size(150, 34);
            uiLabel1.TabIndex = 5;
            uiLabel1.Text = "用户账号:";
            uiLabel1.TextAlign = ContentAlignment.MiddleLeft;
            //
            // Frm_Login
            //
            AutoScaleDimensions = new SizeF(11F, 24F);
            AutoScaleMode = AutoScaleMode.Font;
            ClientSize = new Size(800, 450);
            Controls.Add(uiButton1);
            Controls.Add(uiTextBox2);
            Controls.Add(uiLabel2);
            Controls.Add(uiTextBox1);
            Controls.Add(uiLabel1);
            Name = "Frm_Login";
            Text = "Frm_Login";
            ResumeLayout(false);
        }
        #endregion
        private Sunny.UI.UIButton uiButton1;
        private Sunny.UI.UITextBox uiTextBox2;
        private Sunny.UI.UILabel uiLabel2;
        private Sunny.UI.UITextBox uiTextBox1;
        private Sunny.UI.UILabel uiLabel1;
    }
}
src/Bro.M141.Process/UI/Frm_Login.cs
New file
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Bro.M141.Process.UI
{
    public partial class Frm_Login : Form
    {
        public Frm_Login()
        {
            InitializeComponent();
        }
        private static Frm_Login _instance;
        public static Frm_Login GetInstance()
        {
            if (_instance == null || _instance.IsDisposed)
            {
                _instance = new Frm_Login();
            }
            return _instance;
        }
        public delegate void ChangeBoolHander(bool isAmin);
        public event ChangeBoolHander changeBool;
        public bool isAmin = false;
        private void uiButton1_Click(object sender, EventArgs e)
        {
            if (uiTextBox1.Text == "管理员")
            {
                if (uiTextBox2.Text == "123")
                {
                    uiTextBox2.Text = "";
                    //DataPrinter.GetInstance().Data_Textbox.Enabled = true;
                    //DataPrinter.GetInstance().ISOK = true;
                    isAmin = true;
                    changeBool(isAmin);
                    this.Close();
                }
                else
                {
                    MessageBox.Show("登入密码错误");
                    uiTextBox2.Text = "";
                }
            }
            else
            {
                MessageBox.Show("登入账户不存在");
                uiTextBox1.Text = "";
            }
        }
    }
}
src/Bro.M141.Process/UI/Frm_Login.resx
New file
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!--
    Microsoft ResX Schema
    Version 2.0
    The primary goals of this format is to allow a simple XML format
    that is mostly human readable. The generation and parsing of the
    various data types are done through the TypeConverter classes
    associated with the data types.
    Example:
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
    There are any number of "resheader" rows that contain simple
    name/value pairs.
    Each data row contains a name, and value. The row also contains a
    type or mimetype. Type corresponds to a .NET class that support
    text/value conversion through the TypeConverter architecture.
    Classes that don't support this are serialized and stored with the
    mimetype set.
    The mimetype is used for serialized objects, and tells the
    ResXResourceReader how to depersist the object. This is currently not
    extensible. For a given mimetype the value must be set accordingly:
    Note - application/x-microsoft.net.object.binary.base64 is the format
    that the ResXResourceWriter will generate, however the reader can
    read any of the formats listed below.
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.
    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>
src/Bro.M141.Process/UI/UIPrinter.cs
@@ -84,8 +84,15 @@
            string status = GetPrinterStatusMessage(statuscode);
            //Config141
            try
            {
            Process141.PlcwritePrinter(1520, 0);
            Process141.PlcwritePrinter(1510, 1);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
@@ -121,8 +128,8 @@
                {
                    DisableECI = true,//设置内容编码
                    CharacterSet = "UTF-8",  //设置二维码的宽度和高度
                    Width = 123,
                    Height = 123,
                    Width = 60,
                    Height = 60,
                    Margin = 1//设置二维码的边距,单位不是固定像素
                };
src/Bro.M141_AOI1.Process/AOI1Process.cs
@@ -283,6 +283,7 @@
                    }
                    else
                    {
                        LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"已关闭mes连接");
                        Plc1.WriteSingleAddress(1524, 1, out _);
                        Plc1.WriteSingleAddress(1514, 1, out _);
                    }
@@ -606,6 +607,7 @@
            }
            else
            {
                LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"已关闭mes连接");
                Plc1.WriteSingleAddress(1590, 1, out _);
            }
@@ -686,6 +688,7 @@
            }
            else
            {
                LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"已关闭mes连接");
                Plc1.WriteSingleAddress(1590, 1, out _);
            }
@@ -754,6 +757,7 @@
            }
            else
            {
                LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"已关闭mes连接");
                Plc1.WriteSingleAddress(1591, 1, out _);
            }
@@ -865,6 +869,7 @@
            }
            else
            {
                LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"已关闭mes连接");
                Plc1.WriteSingleAddress(1591, 1, out _);
            }
            return msg;