考勤系统功能实现——打卡

1.打卡界面 ID卡放到读卡器上后点击如图上的寻卡
考勤系统功能实现——打卡
文章图片
打卡 选择串口然后写入职员编号

考勤系统功能实现——打卡
文章图片
打卡2 2.相关代码 自动获取串口列表

private void ServiceForm_Load(object sender, EventArgs e) { // [TODO] 自动获取串口列表并显示到comboBoxCOMList中 string[] ArryPort = SerialPort.GetPortNames(); comboBoxCOMList.Items.Clear(); for (int i = 0; i < ArryPort.Length; i++) { comboBoxCOMList.Items.Add(ArryPort[i]); } }/// /// 初始化串口参数 /// private void InitSerialPort() { // [TODO] 设置串口参数 serialPort1.PortName = comboBoxCOMList.Text; serialPort1.BaudRate = 115200; serialPort1.DataBits = 8; serialPort1.Parity = Parity.None; }/// /// 从RFID卡中读取职员编号,数据位于第00块中 /// /// RFID卡自身编号 /// 数据块索引号 /// 职员编号 private string ReadSingleBlock(string UID, string strBlockIndex) { // 格式化读写命令 string command = string.Format(ISO15693Card.COMMAND_READ_SINGLE_BLOCK, UID, strBlockIndex); serialPort1.Write(command); // 写命令 Thread.Sleep(MILLISECOND_IN_SLEEP); // 睡眠一段时间string response = ""; if (serialPort1.BytesToRead > 0) { response = serialPort1.ReadExisting(); string stuffId = ISO15693CardHandler.GenerateBlockData(response); stuffId = stuffId.TrimStart('0'); this.toolStripStatusLabel1.Text = "读取到职员编号为" + stuffId; return stuffId; }return null; }

向卡中写入数据
/// /// 向RFID卡第00块写入职员编号 /// /// RFID卡自身编号 /// 数据块索引号 /// 职员编号(十六进制,八字节,如'66060000') /// 写入是否成功 private bool WriteSingleBlock(string UID, string strBlockIndex, string hexData) { // 格式化命令 string command = string.Format(ISO15693Card.COMMAND_WRITE_SINGLE_BLOCK, UID, strBlockIndex, hexData); serialPort1.Write(command); Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) { string response = serialPort1.ReadExisting(); return true; }return false; }

打开或关闭串口
/// /// 打开或关闭串口 /// /// /// private void buttonOpenCOM_Click(object sender, EventArgs e) { // 串口已打开,此时需要关闭 if (serialPort1.IsOpen) { serialPort1.Close(); this.toolStripStatusLabel1.Text = "已关闭串口" + serialPort1.PortName.ToString(); buttonOpenCOM.Text = "打开"; return; } // 否则打开串口 else { serialPort1.PortName = comboBoxCOMList.Text; InitSerialPort(); try { serialPort1.Open(); this.toolStripStatusLabel1.Text = "已打开串口" + serialPort1.PortName.ToString(); buttonOpenCOM.Text = "关闭"; } catch (Exception ex) { this.toolStripStatusLabel1.Text = "打开串口失败,原因:" + ex.Message; return; } } }

窗口关闭时,要关闭串口
/// /// 窗口关闭时,要关闭串口 /// /// 【考勤系统功能实现——打卡】 /// private void ServiceForm_FormClosing(object sender, FormClosingEventArgs e) { // 如果关闭窗口时,串口仍然为打开状态,则需要关闭串口 if (serialPort1.IsOpen) { serialPort1.Close(); } }

“读取卡片”按钮的处理方法
/// /// “读取卡片”按钮的处理方法 /// /// /// private void btnReadCard_Click(object sender, EventArgs e) { if (!serialPort1.IsOpen) { this.toolStripStatusLabel1.Text = "请先打开串口"; return; } //this.toolStripStatusLabel1.Text = "未找到有效的卡"; // [TODO] 寻卡,将RFID卡号读出来 string response = ""; serialPort1.Write(ISO15693Card.COMMAND_WRITE_REG); Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) response = serialPort1.ReadExisting(); serialPort1.Write(ISO15693Card.COMMAND_SET_AGC); Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) response = serialPort1.ReadExisting(); serialPort1.Write(ISO15693Card.COMMAND_SET_RECV_MODE); Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) response = serialPort1.ReadExisting(); serialPort1.Write(ISO15693Card.COMMAND_INVEN_CARD); // 寻卡 Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) response = serialPort1.ReadExisting(); List cards = ISO15693CardHandler.InventoryCard(response); // [TODO] 读取卡上第00块的数据,获得职员编号 String stuffId = ReadSingleBlock(ISO15693CardHandler.CovertEndian(cards[0].ID), "00"); // [TODO] 向数据库中插入一条打卡记录,插入成功后显示打卡成功 //// DateTime.Now.ToString(); // 默认格式的日期和时间 //// DateTime.Now.ToString(“yyyy - MM - dd HH: mm:ss”); ??// 指定格式:2018-04-09 21:02:10 //// 获取日期?DateTime.Now.ToShortDateString(); //// 默认日期格式?DateTime.Now.ToString(“yyyy-MM-dd”); ? ////指定日期格式:2018-04-09?// 获取时间?DateTime.Now.ToLongTimeString(); ?? //// 默认时间格式?DateTime.Now.ToString(“hh:mm:ss”); ??????? //// 指定时间格式:09:02:10String connStr = ConfigurationManager.ConnectionStrings["SuperMarketSales"].ConnectionString; SqlConnection sqlConn = new SqlConnection(connStr); try { // 连接数据库 sqlConn.Open(); // 构造命令 String sqlStr = "insert into record(employee_id, date, time, machine_id) VALUES(@Employee_id, @date,@time, @machine_id)"; SqlCommand cmd = new SqlCommand(sqlStr, sqlConn); // SQL字符串参数赋值 cmd.Parameters.Add(new SqlParameter("@employee_id", stuffId)); cmd.Parameters.Add(new SqlParameter("@date", DateTime.Now.ToString("yyyy - MM - dd").ToString())); cmd.Parameters.Add(new SqlParameter("@time", DateTime.Now.ToString("HH: mm:ss").ToString())); cmd.Parameters.Add(new SqlParameter("@machine_id", '1')); // 将命令发送给数据库 int res = cmd.ExecuteNonQuery(); // 根据返回值判断是否插入成功 if (res != 0) { MessageBox.Show("打卡成功"); } else { MessageBox.Show("打卡失败"); } } catch (Exception exp) { MessageBox.Show("访问数据库错误:" + exp.Message); } finally { sqlConn.Close(); }

注册新卡并写入数据
}/// /// 注册新卡,往第00块写入职员编号 /// /// /// private void bt_Register_Click(object sender, EventArgs e) { if (!serialPort1.IsOpen) { this.toolStripStatusLabel1.Text = "请先打开串口"; return; }//this.toolStripStatusLabel1.Text = "未找到有效的卡"; // '666'填充为'00000666' string stuffId = this.tb_EmployeeId.Text.PadLeft(8, '0'); // '00000666'转变成'66060000' stuffId = ISO15693CardHandler.CovertEndian(stuffId); // 检查输入数据的错误 // ISO15693为32位,4字节,8字符 if (stuffId.Length != 8) { MessageBox.Show("请输入4字节的16进制数据!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }// 检查16进制字符错误 if (!ISO15693CardHandler.CheckValidHexBytes(stuffId)) { MessageBox.Show("写入数据的16进制格式错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }// [TODO] 寻卡,将RFID卡号读出来 string response = ""; serialPort1.Write(ISO15693Card.COMMAND_WRITE_REG); Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) response = serialPort1.ReadExisting(); serialPort1.Write(ISO15693Card.COMMAND_SET_AGC); Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) response = serialPort1.ReadExisting(); serialPort1.Write(ISO15693Card.COMMAND_SET_RECV_MODE); Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) response = serialPort1.ReadExisting(); serialPort1.Write(ISO15693Card.COMMAND_INVEN_CARD); // 寻卡 Thread.Sleep(MILLISECOND_IN_SLEEP); if (serialPort1.BytesToRead > 0) response = serialPort1.ReadExisting(); List cards = ISO15693CardHandler.InventoryCard(response); // [TODO] 向RFID卡第00块写入职员编号数据,无论成功与否,均应该在状态栏显示提示信息//写单块数据//检查输入数据的错误 //ISO15693为32位,4字节,8字符 if (tb_EmployeeId.Text.Length != 8) { MessageBox.Show("请输入4字节的16进制数据!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }//检查16进制字符错误 if (!ISO15693CardHandler.CheckValidHexBytes(tb_EmployeeId.Text)) { MessageBox.Show("写入数据的16进制格式错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { WriteSingleBlock(ISO15693CardHandler.CovertEndian(cards[0].ID), "00", tb_EmployeeId.Text); this.toolStripStatusLabel1.Text = "写入成功"; }}

    推荐阅读