中控考勤机接口开发
本文参考手册:《TFT 系列脱机通讯开发包开发手册》
业务需求:
1、定时同步考勤机的刷卡记录到数据库
2、推送人员信息到考勤机
主要内容:
1、定时同步考勤记录到数据库
2、用户信息、指纹操作
3、考勤记录批量操作
正文
1、定时任务
1-1、定义全局变量
1 #region 窗体变量 2 string USERID = "";//同步到数据库的参数 3 string CHARGE_TIME = "";//同步到数据库的参数 4 string VERIFYMODE = "";//同步到数据库的参数 5 string WORKCODE = "";//同步到数据库的参数 6 string PASSWORD = "";//同步到数据库的参数 7 string PRIVILEGE = "";//同步到数据库的参数 8 string ENABLE = "";//同步到数据库的参数 9 System.Timers.Timer atimer = new System.Timers.Timer(); //定时任务 10 #endregion 11 12 #region 考勤机变量 13 public CZKEMClass axCZKEM1 = new CZKEMClass(); 14 private bool bIsConnected = false; 15 private int iMachineNumber = 1; 16 17 string sdwEnrollNumber = "";//用户ID 18 string sName = "";//姓名 19 string sPassword = "";//密码 20 int iPrivilege = 0; 21 bool bEnabled = false; 22 string sCardnumber = "";//卡号 23 int dwWorkCode = 0; 24 int dwVerifyMode; 25 int dwInOutMode; 26 int dwYear;//刷卡时间 27 int dwMonth; 28 int dwDay; 29 int dwHour; 30 int dwMinute; 31 int dwSecond; 32 string verifyMode = ""; 33 string privilege = ""; 34 string enabled = ""; 35 #endregion
1-2、连接考勤机
1 #region 考勤机功能:打开连接 2 private void connectZK() 3 { 4 //若IP、端口号为空则不能连接 5 if (txtIP.Text.Trim() == "" || txtPort.Text.Trim() == "") 6 { 7 WriteLog.Write("WARN", txtIP.Text, "打开连接时IP或端口不能为空"); 8 return; 9 } 10 //若状态为已连接则先关闭连接 11 if (bIsConnected == true) 12 { 13 disconnectZK(); 14 } 15 //连接机器 16 int idwErrorCode = 0; 17 Cursor = Cursors.WaitCursor; 18 bIsConnected = axCZKEM1.Connect_Net(txtIP.Text, Convert.ToInt32(txtPort.Text)); 19 if (bIsConnected == true) 20 { 21 lblState.Text = "Current State:Connected"; 22 iMachineNumber = 1;//In fact,when you are using the tcp/ip communication,this parameter will be ignored,that is any integer will all right.Here we use 1. 23 axCZKEM1.RegEvent(iMachineNumber, 65535);//Here you can register the realtime events that you want to be triggered(the parameters 65535 means registering all) 24 WriteLog.Write("INFO", txtIP.Text, "连接成功。"); 25 } 26 else 27 { 28 axCZKEM1.GetLastError(ref idwErrorCode); 29 WriteLog.Write("WARN", txtIP.Text, "连接失败。ErrorCode=" + idwErrorCode.ToString()); 30 } 31 Cursor = Cursors.Default; 32 } 33 #endregion 34 35 #region 考勤机功能:关闭连接 36 private void disconnectZK() 37 { 38 if (txtIP.Text.Trim() == "" || txtPort.Text.Trim() == "") 39 { 40 WriteLog.Write("WARN", txtIP.Text, "关闭连接时IP或端口不能为空"); 41 return; 42 } 43 44 Cursor = Cursors.WaitCursor; 45 if (bIsConnected) 46 { 47 axCZKEM1.Disconnect(); 48 bIsConnected = false; 49 lblState.Text = "Current State:DisConnected"; 50 WriteLog.Write("INFO", txtIP.Text, "连接关闭。"); 51 Cursor = Cursors.Default; 52 return; 53 } 54 else 55 { 56 Cursor = Cursors.Default; 57 } 58 } 59 #endregion
1-3、配置定时任务
这里使用.net工具箱提供的定时器System.Windows.Forms.Timer。
需要同步记录或推送人员时再打开连接,否则可能会出现因连接时间过长导致连接失去响应。
1 #region 定时任务配置 2 private void timerSync_Tick(object sender, EventArgs e) 3 { 4 int nowhour = int.Parse(DateTime.Now.Hour.ToString()); 5 int nowminute = int.Parse(DateTime.Now.Minute.ToString()); 6 // 8:00~23:00 7 if (nowhour >= 8 && nowhour <= 22) 8 { 9 // 打开连接 10 connectZK(); 11 if (bIsConnected == true) 12 { 13 // 同步刷卡 14 getLogData(); 15 // 关闭连接 16 disconnectZK(); 17 } 18 } 19 // 23:00 20 if (nowhour == 23 && nowminute == 00) 21 { 22 // 打开连接 23 connectZK(); 24 if (bIsConnected == true) 25 { 26 // 清空考勤机刷卡记录 27 clearRecord(); 28 // 推送人员 29 pushEmp(); 30 // 关闭连接 31 disconnectZK(); 32 } 33 } 34 } 35 #endregion
1-4、同步刷卡记录
1 #region 任务-同步刷卡数据到MES数据库 2 private void getLogData() 3 { 4 if (bIsConnected == false) 5 { 6 WriteLog.Write("WARN", "", "当前未连接考勤机"); 7 return; 8 } 9 Cursor = Cursors.WaitCursor; 10 //先禁用机器 11 axCZKEM1.EnableDevice(iMachineNumber, false); 12 //获取所有用户的考勤记录到缓存区 13 axCZKEM1.ReadAllGLogData(iMachineNumber); 14 while (axCZKEM1.SSR_GetGeneralLogData(iMachineNumber, out sdwEnrollNumber, out dwVerifyMode, out dwInOutMode, out dwYear, out dwMonth, out dwDay, out dwHour, out dwMinute, out dwSecond, ref dwWorkCode))//get user information from memory 15 { 16 switch (dwVerifyMode) 17 { 18 case 0: 19 verifyMode = "密码验证"; 20 break; 21 case 1: 22 verifyMode = "指纹验证"; 23 break; 24 case 2: 25 verifyMode = "卡验证"; 26 break; 27 default: 28 verifyMode = "其他验证"; 29 break; 30 } 31 //循环获取用户信息 32 axCZKEM1.SSR_GetUserInfo(iMachineNumber, sdwEnrollNumber, out sName, out sPassword, out iPrivilege, out bEnabled); 33 if (axCZKEM1.GetStrCardNumber(out sCardnumber))//get the card number from the memory 34 { 35 switch (iPrivilege) 36 { 37 case 0: 38 privilege = "普通用户"; 39 break; 40 case 3: 41 privilege = "管理员"; 42 break; 43 default: 44 privilege = "其他权限"; 45 break; 46 } 47 switch (bEnabled) 48 { 49 case true: 50 enabled = "启用"; 51 break; 52 case false: 53 enabled = "禁用"; 54 break; 55 } 56 USERID = sdwEnrollNumber; 57 CHARGE_TIME = dwYear.ToString() + "-" + dwMonth.ToString() + "-" + dwDay.ToString() + " " + dwHour.ToString() + ":" + dwMinute.ToString() + ":" + dwSecond.ToString(); 58 CHARGE_DATE = dwYear.ToString("0000") + "-" +dwMonth.ToString("00") + "-" + dwDay.ToString("00"); 59 VERIFYMODE = verifyMode; 60 WORKCODE = dwWorkCode.ToString(); 61 //NAME = sName+ "\0"; 62 //NAME = NAME.Replace("\0", ""); 63 PASSWORD = sPassword; 64 PRIVILEGE = privilege; 65 ENABLE = enabled; 66 string ID = dwYear.ToString() + dwMonth.ToString() + dwDay.ToString() + dwHour.ToString() + dwMinute.ToString() + dwSecond.ToString(); 67 DateTime now = DateTime.Now; 68 string thisyear = now.Year.ToString(); 69 string thismonth = now.Month.ToString(); 70 string thisday = now.Day.ToString(); 71 // 仅同步当天的刷卡记录 72 if (dwYear.ToString() == thisyear && dwMonth.ToString() == thismonth && dwDay.ToString() == thisday) 73 { 74 // 这个调用插入数据库的方法 75 WriteLog.Write("INFO", "", "同步刷卡记录到数据库"); 76 } 77 } 78 } 79 axCZKEM1.EnableDevice(iMachineNumber, true);//enable the device 80 Cursor = Cursors.Default; 81 } 82 #endregion
1-5、推送数据库中人员到考勤机
1 private void pushEmp() 2 { 3 if (bIsConnected == false) 4 { 5 WriteLog.Write("WARN", "", "当前未连接考勤机"); 6 return; 7 } 8 //获取orcale表推送状态为0的人员,推送到考勤机 9 DataTable pushdt = BllEmpSync.pushEmp(); 10 string[] push_num = new string[pushdt.Rows.Count]; 11 string[] push_name = new string[pushdt.Rows.Count]; 12 string[] push_cardnum = new string[pushdt.Rows.Count]; 13 WriteLog.Write("INFO", txtIP.Text, "开始推送人员信息...待推送人员数:" + pushdt.Rows.Count.ToString()); 14 for (int i = 0; i < pushdt.Rows.Count; i++) 15 { 16 DataRow dr = pushdt.Rows[i]; 17 push_num[i] = Convert.ToString(dr["T_USERID"]); 18 push_name[i] = Convert.ToString(dr["T_USERNAME"]); 19 push_cardnum[i] = Convert.ToString(dr["CARDID"]); 20 axCZKEM1.SetStrCardNumber(push_cardnum[i]); 21 //2、设置用户信息 22 bool a = axCZKEM1.SSR_SetUserInfo(iMachineNumber, push_num[i], push_name[i], push_num[i], 0, true); 23 if (a) WriteLog.Write("INFO", txtIP.Text, "推送人员" + push_num[i] + "成功。"); 24 else WriteLog.Write("WARN", txtIP.Text, "推送人员" + push_num[i] + "失败。"); 25 } 26 BllEmpSync.updateEmp(); 27 }
1-6、每天定时清空考勤机刷卡记录
(防止同步时因数据太多而变卡,调用方法见2-7)
2、考勤机管理(注:以下方法省略了考勤机的打开与关闭连接)
2-1、查询考勤机内已注册用户
(注意:如果考勤机内没有注册指纹信息,代码里面有查询指纹,那么加载会变得非常慢。要提前注释掉查询指纹的代码!)
1 #region 考勤机功能:获取用户 2 private void btnGetStrCardNumber_Click(object sender, EventArgs e) 3 { 4 if (bIsConnected == false) 5 { 6 MessageBox.Show("Please connect the device first!", "Error"); 7 return; 8 } 9 lvCard.Items.Clear(); 10 lvCard.BeginUpdate(); 11 Cursor = Cursors.WaitCursor; 12 //先禁用机器 13 axCZKEM1.EnableDevice(iMachineNumber, false);//disable the device 14 //获取所有用户的记录到缓存区 15 axCZKEM1.ReadAllUserID(iMachineNumber);//获取所有信息到缓存区(提高效率) 16 axCZKEM1.ReadAllTemplate(iMachineNumber);//获取所有指纹信息到缓存区(提高效率) 17 while (axCZKEM1.SSR_GetAllUserInfo(iMachineNumber, out sdwEnrollNumber, out sName, out sPassword, out iPrivilege, out bEnabled))//get user information from memory 18 { 19 //循环获取用户信息 20 if (axCZKEM1.GetStrCardNumber(out sCardnumber))//get the card number from the memory 21 { 22 ListViewItem list = new ListViewItem(); 23 list.Text = sdwEnrollNumber; 24 list.SubItems.Add(sName); 25 list.SubItems.Add(sCardnumber); 26 list.SubItems.Add(iPrivilege.ToString()); 27 list.SubItems.Add(sPassword); 28 if (bEnabled == true) 29 { 30 list.SubItems.Add("true"); 31 } 32 else 33 { 34 list.SubItems.Add("false"); 35 } 36 37 for (int dwFingerIndex = 0; dwFingerIndex < 10; dwFingerIndex++) 38 { 39 if (axCZKEM1.SSR_GetUserTmpStr(iMachineNumber, sdwEnrollNumber, dwFingerIndex, out dwTmpData, out dwTmpLength)) 40 { 41 list.SubItems.Add(dwTmpData); 42 } 43 else 44 { 45 list.SubItems.Add(""); 46 } 47 } 48 49 lvCard.Items.Add(list); 50 } 51 } 52 53 axCZKEM1.EnableDevice(iMachineNumber, true);//enable the device 54 lvCard.EndUpdate(); 55 Cursor = Cursors.Default; 56 } 57 #endregion
2-2、注册单个用户到考勤机
1 #region 考勤机功能:注册用户 2 private void btnSetStrCardNumber_Click(object sender, EventArgs e) 3 { 4 if (bIsConnected == false) 5 { 6 MessageBox.Show("Please connect the device first!", "Error"); 7 return; 8 } 9 //下发用户到机器 10 //1、设置卡号 11 //string CardNo = System.Convert.ToInt32(txtCardNo.Text, 16).ToString();//转换16进制到十进制 12 axCZKEM1.SetStrCardNumber(txtCardNo.Text); 13 //2、设置用户信息 14 axCZKEM1.SSR_SetUserInfo(iMachineNumber, "用户ID", "用户姓名", "密码", 0, true); 15 } 16 #endregion
2-3、批量注册用户
1 #region 考勤机功能:批量注册用户 2 private void btnSetStrCardNumbers_Click(object sender, EventArgs e) 3 { 4 if (XCMessageBox.Show("确定?", XCMessageBox.Buttons.OKCancel, XCMessageBox.Icon.Question) == DialogResult.OK) 5 { 6 System.Data.DataTable dt = getEmp();//getEmp()获取数据库中需要注册的用户 7 string[] useruid = new string[dt.Rows.Count]; 8 string[] useruname = new string[dt.Rows.Count]; 9 string[] cardid = new string[dt.Rows.Count]; 10 for (int i = 0; i < dt.Rows.Count; i++) 11 { 12 DataRow dr = dt.Rows[i]; 13 useruid[i] = Convert.ToString(dr["T_USERID"]); 14 useruname[i] = Convert.ToString(dr["T_USERNAME"]); 15 cardid[i] = Convert.ToString(dr["CARDID"]); 16 //16进制转10进制 17 //string CardNo = System.Convert.ToInt32(cardid[i], 16).ToString(); 18 axCZKEM1.SetStrCardNumber(cardid[i]); 19 //2、设置用户信息 20 bool a = axCZKEM1.SSR_SetUserInfo(iMachineNumber, useruid[i], useruname[i], useruid[i], 0, true); 21 } 22 } 23 } 24 #endregion
2-4、删除用户
1 #region 考勤机功能:删除用户 2 private void btnDelStrCardNumber_Click(object sender, EventArgs e) 3 { 4 if (bIsConnected == false) 5 { 6 MessageBox.Show("Please connect the device first!", "Error"); 7 return; 8 } 9 if (XCMessageBox.Show("确定?", XCMessageBox.Buttons.OKCancel, XCMessageBox.Icon.Question) == DialogResult.OK) 10 { 11 axCZKEM1.SSR_DeleteEnrollData(iMachineNumber, "用户ID", 12); 12 } 13 } 14 #endregion
2-5、增删指纹
(这里有一点要注意:考勤机算法不同的话,增加指纹所调用的方法不同,使用前先查看考勤机算法)
1 #region 考勤机功能:增删指纹 2 private void btnDelTmp_Click(object sender, EventArgs e) 3 { 4 if (bIsConnected == false) 5 { 6 MessageBox.Show("Please connect the device first!", "Error"); 7 return; 8 } 9 if (XCMessageBox.Show("确定?", XCMessageBox.Buttons.OKCancel, XCMessageBox.Icon.Question) == DialogResult.OK) 10 { 11 bool a = axCZKEM1.SSR_DelUserTmp(iMachineNumber, "用户ID", "(int)第几个指纹"); 12 //bool a = axCZKEM1.SSR_DeleteEnrollDataExt(iMachineNumber, txtEmpNo.Text, 13);//删除所有指纹 13 } 14 } 15 16 private void btnAddTmp_Click(object sender, EventArgs e) 17 { 18 if (bIsConnected == false) 19 { 20 MessageBox.Show("Please connect the device first!", "Error"); 21 return; 22 } 23 System.Data.DataTable dt = new System.Data.DataTable(); 24 for (int i = 0; i < 10; i++) 25 { 26 27 //循环获取十个指纹 28 dt = getEmpTmp(i.ToString());//获取数据库中第i个指纹 29 for (int j = 0; j < dt.Rows.Count; j++) 30 { 31 32 //循环数据库中的用户数 33 USERID = dt.Rows[j]["数据库中用户ID"].ToString(); 34 dwTmpData = dt.Rows[j]["数据库中第i个指纹"].ToString(); 35 bool a = axCZKEM1.SetUserTmpExStr(iMachineNumber, USERID, i, 1, dwTmpData); 36 } 37 } 38 39 //获取算法版本 40 /*string sValue; 41 axCZKEM1.GetSysOption(1, "~ZKFPVersion", out sValue); 42 txtInfo.Text = sValue;*/ 43 } 44 #endregion
2-6、清空考勤机所有注册的用户
1 #region 考勤机功能:清空考勤机用户 2 private void btnDel_Click(object sender, EventArgs e) 3 { 4 if (bIsConnected == false) 5 { 6 MessageBox.Show("Please connect the device first!", "Error"); 7 return; 8 } 9 if (XCMessageBox.Show("确定?", XCMessageBox.Buttons.OKCancel, XCMessageBox.Icon.Question) == DialogResult.OK) 10 { 11 Cursor = Cursors.WaitCursor; 12 //先禁用机器 13 axCZKEM1.EnableDevice(iMachineNumber, false);//disable the device 14 //获取所有用户的记录到缓存区 15 axCZKEM1.ReadAllUserID(iMachineNumber);//获取所有信息到缓存区(提高效率) 16 while (axCZKEM1.SSR_GetAllUserInfo(iMachineNumber, out sdwEnrollNumber, out sName, out sPassword, out iPrivilege, out bEnabled))//get user information from memory 17 { 18 axCZKEM1.SSR_DeleteEnrollDataExt(iMachineNumber, sdwEnrollNumber, 12); 19 } 20 21 axCZKEM1.EnableDevice(iMachineNumber, true);//enable the device 22 Cursor = Cursors.Default; 23 } 24 } 25 #endregion
2-7、清空考勤机所有刷卡记录
1 #region 考勤机功能:清空考勤记录 2 private void btnDelLogData_Click(object sender, EventArgs e) 3 { 4 if (bIsConnected == false) 5 { 6 MessageBox.Show("Please connect the device first!", "Error"); 7 return; 8 } 9 if (XCMessageBox.Show("确定?", XCMessageBox.Buttons.OKCancel, XCMessageBox.Icon.Question) == DialogResult.OK) 10 { 11 axCZKEM1.ClearGLog(iMachineNumber); 12 } 13 } 14 #endregion