using System; using System.Data; using System.Net; using System.Net.Sockets; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace HL_RFIDAutomaticInductionTime { public partial class RFIDService : ServiceBase { #region 变量 /// /// 同步锁 /// private static object syncRoot = new object(); /// /// 日志文件路径 /// private string logPath = Application.StartupPath + @"\Log"; /// /// 日志文件 /// FileClass fileClass = new FileClass(); /// /// 初始化配置文件 /// Config config = new Config(); /// /// 数据库访问类 /// SqlDBHelper sqlDBHelp = new SqlDBHelper(); /// /// 手腕带/标签卡源 /// private DataTable labelDT = new DataTable(); /// /// 时间格式字符 /// private string timeToString = "yyyy-MM-dd HH:mm:ss fff"; #endregion public RFIDService() { InitializeComponent(); InitService(); } #region Windows服务私有方法 /// /// 服务开启执行代码 /// /// protected override void OnStart(string[] args) { MessageAdd(config.ServiceName + "已成功启动!"); } /// /// 服务结束执行代码 /// protected override void OnStop() { MessageAdd(config.ServiceName + "已停止!"); } /// /// 服务恢复执行代码 /// protected override void OnContinue() { base.OnContinue(); } /// /// 服务暂停执行代码 /// protected override void OnPause() { base.OnPause(); } /// /// 系统即将关闭执行代码 /// protected override void OnShutdown() { base.OnShutdown(); } #endregion #region 自定义方法 /// /// 初始化服务参数 /// private void InitService() { base.CanShutdown = true; base.CanStop = true; base.CanPauseAndContinue = true; this.ServiceName = config.ServiceName; this.AutoLog = false;//为了使用自定义日志,必须将 AutoLog 设置为 false StarServer(config.StrPort); } /// /// 日志记录 /// /// 内容 public void MessageAdd(string str) { try { fileClass.WriteLogFile(logPath, str);//写入记录日志 } catch { } } #endregion /// /// 开启监听服务 /// /// 指定端口号 private void StarServer(int strPort) { try { //点击开始监听时 在服务端创建一个负责监听IP和端口号的Socket Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ip = IPAddress.Any; //创建对象端口 IPEndPoint point = new IPEndPoint(ip, strPort); socketWatch.Bind(point);//绑定端口号 MessageAdd(string.Format("端口{0}监听成功! {1}", strPort, DateTime.Now.ToString(timeToString))); socketWatch.Listen(10);//设置监听 //创建监听线程 Thread thread = new Thread(Listen); thread.IsBackground = true; thread.Start(socketWatch); } catch (Exception ex) { MessageAdd(string.Format("错误:端口{0}监听失败! {1},详细信息如下:\r\n{2}", strPort, DateTime.Now.ToString(timeToString), ex)); } } /// /// 等待客户端的连接 并且创建与之通信的Socket /// Socket socketSend; private void Listen(object o) { try { Socket socketWatch = o as Socket; while (true) { socketSend = socketWatch.Accept();//等待接收客户端连接 MessageAdd(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功!" + " " + DateTime.Now.ToString(timeToString)); //开启一个新线程,执行接收消息方法 Thread r_thread = new Thread(Received); r_thread.IsBackground = true; r_thread.Start(socketSend); } } catch (Exception ex) { MessageAdd(string.Format("错误:{0}:连接失败! {1},详细信息如下:\r\n{2}", socketSend.RemoteEndPoint.ToString(), DateTime.Now.ToString(timeToString), ex)); } } /// /// 服务器端不停的接收客户端发来的消息 /// /// private void Received(object o) { try { Socket socketSend = o as Socket; while (true) { //客户端连接服务器成功后,服务器接收客户端发送的消息 //byte[] buffer = new byte[17]; byte[] buffer = new byte[5]; //实际接收到的有效字节数 int len = socketSend.Receive(buffer); if (len == 0) { break; } string str = ByteToHexStr(buffer); MessageAdd(str + "长度" + str.Length); //MessageAdd(str.Substring(0, 2).ToString()+"----"+ str.Substring(32, 2).ToString()); //if (str.Substring(0, 2).ToString() == "00" && str.Substring(32, 2).ToString() == "FF") if (str.Length >= 10) { //时间统一 DateTime RecordingTime = DateTime.Now; MessageAdd(str + " 感应时间【 " + RecordingTime.ToString() + "】"); //开启新线程处理数据 Task t = Task.Factory.StartNew(() => { //开启调试模式 //if (config.IsDebug) // { // MessageAdd("异步更新数据开始" + DateTime.Now.ToString(timeToString)); // } Thread.SpinWait(60000);//线程等待1分钟 //数据处理 DataProcessing(str, RecordingTime); //开启调试模式 //if (config.IsDebug) // { // MessageAdd("异步更新数据结束" + DateTime.Now.ToString(timeToString)); // } }); //开启调试模式 //if (config.IsDebug) //{ // MessageAdd("继续监听开始" + DateTime.Now.ToString(timeToString)); //} } } } catch (Exception ex) { MessageAdd(string.Format("错误:{0}:接收信息失败! {1},详细信息如下:\r\n{2}", socketSend.RemoteEndPoint, DateTime.Now.ToString(timeToString), ex)); } } /// /// 服务器向客户端发送消息 /// /// private void Send(string str) { byte[] buffer = Encoding.Unicode.GetBytes(str); socketSend.Send(buffer); } /// /// 字节数组转16进制字符串 /// /// /// public static string ByteToHexStr(byte[] bytes) { string returnStr = ""; if (bytes != null) { for (int i = 0; i < bytes.Length; i++) { returnStr += bytes[i].ToString("X2");//ToString("X2") 为C#中的字符串格式控制符 } } return returnStr; } /// /// 16进制字符串转字节数组 格式为 string sendMessage = "00 01 00 00 00 06 FF 05 00 64 00 00"; /// /// /// private static byte[] HexStrTobyte(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Trim(), 16); return returnBytes; } /// /// 开始数据处理 /// /// 接收的字符 /// 时间:统一各步骤时间 private void DataProcessing(string dataStr, DateTime time) { //开始数据处理 if (!string.IsNullOrEmpty(dataStr)) { //if (dataStr.Length >= 28) if (dataStr.Length == 10) { //标签卡编号 //string Code = dataStr.Substring(4, 24);//刷卡感应标签卡编号不一样 string Code = dataStr.Substring(2, 8);//刷卡感应标签卡编号不一样 //string Code = dataStr.Substring(4, 6);//有源通过式感应卡 //RFID用户码标志 转换成10进制 //int UserCodeFlag = Convert.ToInt32(dataStr.Substring(2, 2), 16); int UserCodeFlag = Convert.ToInt32(dataStr.Substring(0, 2)); MessageAdd("标签卡编号" + Code + " RFID用户码标志" + UserCodeFlag); //判断当前标签是否有效 是否存在数据库基础表中 if (IsValidLabel(Code)) { //开启新线程更新数据库 UpdateTime(Code, UserCodeFlag, time); } else { //开启调试模式 if (config.IsDebug) { MessageAdd(string.Format("错误:标签卡{0}无效!数据库共{1}个标签 {1}", Code, labelDT.Rows.Count, DateTime.Now.ToString(timeToString))); } } } } else { MessageAdd(string.Format("错误:{0}:接收信息为空! {1}", socketSend.RemoteEndPoint, DateTime.Now.ToString(timeToString))); } } /// /// 判断是否是有效标签 /// /// 标签源 /// 需要判断的标签 /// private bool IsValidLabel(string code) { bool IsValid = false; try { string SqlStr = @"SELECT [ID],[GUID],[Code],[Status],[DeleteFlag],[CreationDate],[CreatorID],[Creator] FROM [T_Base_WristStrap] WHERE DeleteFlag=0"; MessageAdd("标签源SQL:" + SqlStr); MessageAdd("数据库连接语句:" + config.StrCon); labelDT = sqlDBHelp.GetDT(SqlStr, config.StrCon); MessageAdd("数据库获取到的表:" + labelDT.Rows); //开启调试模式 if (config.IsDebug) { MessageAdd("获取到标签源数量为:" + labelDT.Rows.Count + " " + DateTime.Now.ToString(timeToString)); } foreach (DataRow row in labelDT.Rows) { if (code.Trim() == row["Code"].ToString().Trim()) { IsValid = true; break; } } } catch (Exception e) { MessageAdd(e.Message); return IsValid; } return IsValid; } /// /// 更新时间节点时间 /// /// 标签卡编号 /// RFID用户码标志 /// 感应时间 private void UpdateTime(string code, int userCodeFlag, DateTime time) { //Sql变量 string SqlStr = string.Empty; //当前病人GUID string PatientGuid = string.Empty; //当前RFID对应的时间节点编号 string TimeAxisID = string.Empty; //病人信息 DataTable PatientDT = new DataTable(); //RFID对应的时间节点信息 DataTable RfidInstallationAddrDT = new DataTable(); //绑定病人所属系统模块编号 string PatientSystemModuleID = string.Empty; #region 根据 标签卡编号 获取当前绑定的患者 急救中 SqlStr = @"SELECT a.[GUID],[SystemModuleID],[Name],[Age],[MobilePhone],[IdentityCard],[WristStrapID],b.[Code],c.GenderName,d.ShortName FROM [T_Service_Patient] a LEFT JOIN T_Base_WristStrap b on a.WristStrapID=b.ID LEFT JOIN T_Base_Gender c on a.Gender=c.GenderCode LEFT JOIN T_SYS_SystemModule d on a.SystemModuleID=d.ID WHERE b.Code='{0}' and a.EmergencyState=0 and a.DeleteFlag=0 and b.DeleteFlag=0 and d.DeleteFlag=0 ORDER BY a.ID DESC"; SqlStr = string.Format(SqlStr, code); MessageAdd("根据标签卡编号获取当前绑定的患者的SQL " + SqlStr); PatientDT = sqlDBHelp.GetDT(SqlStr, config.StrCon); #endregion //存在病人信息 if (PatientDT != null && PatientDT.Rows.Count > 0) { PatientGuid = PatientDT.Rows[0]["GUID"].ToString(); PatientSystemModuleID = PatientDT.Rows[0]["SystemModuleID"].ToString(); if (!string.IsNullOrEmpty(PatientGuid)) { #region 根据 Rfid用户码标志 获取该设备所对应的时间节点 SqlStr = @"SELECT [Code],[TimeAxisID],b.TimeName FROM [T_Base_RfidInstallationAddr] a LEFT JOIN T_Base_TimeAxis b on a.TimeAxisID=b.ID WHERE a.Code='{0}' and a.DeleteFlag=0 and b.SystemModuleID=" + PatientSystemModuleID; SqlStr = string.Format(SqlStr, userCodeFlag); MessageAdd("根据 Rfid用户码标志 获取该设备所对应的时间节点 " + SqlStr); RfidInstallationAddrDT = sqlDBHelp.GetDT(SqlStr, config.StrCon); #endregion //存在对应的时间节点 //if (RfidInstallationAddrDT != null && RfidInstallationAddrDT.Rows.Count > 0) //{ //循环更新时间节点 foreach (DataRow item in RfidInstallationAddrDT.Rows) { TimeAxisID = item["TimeAxisID"].ToString(); //TimeAxisID = RfidInstallationAddrDT.Rows[0]["TimeAxisID"].ToString(); if (!string.IsNullOrEmpty(TimeAxisID)) { bool IsUpdate = true; #region 开始更新 //胸痛中心系统 if (PatientSystemModuleID == config.ChestPain) { IsUpdate = UpdateChestPainTimeAxis(time, PatientGuid, TimeAxisID); if (IsUpdate) { break; } } //卒中中心系统 else if (PatientSystemModuleID == config.Apoplexy) { IsUpdate = UpdateApoplexyTimeAxis(time, PatientGuid, TimeAxisID); if (IsUpdate) { break; } } //创伤救治中心系统 else if (PatientSystemModuleID == config.Trauma) { } //危重孕产妇救治中心系统 else if (PatientSystemModuleID == config.CriticalPregnant) { } //危重新生儿救治中心系统 else if (PatientSystemModuleID == config.CriticalNeonatal) { } if (IsUpdate) { MessageAdd(string.Format("成功:{0}患者{1},{2},{3}的{4}时间更新成功!{5}", PatientDT.Rows[0]["ShortName"].ToString(), PatientDT.Rows[0]["Name"].ToString(), PatientDT.Rows[0]["GenderName"].ToString(), PatientDT.Rows[0]["Age"].ToString() + "岁", RfidInstallationAddrDT.Rows[0]["TimeName"].ToString(), DateTime.Now.ToString(timeToString))); } else { //开启调试模式 if (config.IsDebug) { MessageAdd(string.Format("失败:{0}患者{1}的{2}已有数据,取消更新!{3}", PatientDT.Rows[0]["ShortName"].ToString(), PatientDT.Rows[0]["Name"].ToString(), RfidInstallationAddrDT.Rows[0]["TimeName"].ToString(), DateTime.Now.ToString(timeToString))); } } #endregion } else { MessageAdd(string.Format("失败:未获取到有效的时间节点编号!{0}", DateTime.Now.ToString(timeToString))); } } //} //else //{ // MessageAdd(string.Format("失败:未获取用户标记为{0}的RFID所对应的时间节点编号!{1}", userCodeFlag, DateTime.Now.ToString(timeToString))); //} } else { MessageAdd(string.Format("失败:未获取到有效的患者编号!{0}", DateTime.Now.ToString(timeToString))); } } else { MessageAdd(string.Format("失败:标签卡{0}未关联到患者信息!{1}", code, DateTime.Now.ToString(timeToString))); } } /// /// 更新胸痛时间节点 /// /// 时间 /// 病人编码 /// 时间节点 /// private bool UpdateChestPainTimeAxis(DateTime time, string patientGuid, string timeAxisID) { bool IsTrue = false; //先判断该病人对应的时间节点是否已经存在数据 string SqlStr = @"SELECT [ID],[RecordingTime],[IsAutoForRFID] FROM [T_Service_ChestPain_PatientsTimeAxis] WHERE PatientGuid='{0}' and TimeAxisID='{1}' and isnull(RecordingTime,'')='' and DeleteFlag=0"; SqlStr = string.Format(SqlStr, patientGuid, timeAxisID); MessageAdd("先判断该病人对应的时间节点是否已经存在数据 " + SqlStr); DataTable CheckDT = sqlDBHelp.GetDT(SqlStr, config.StrCon); if (CheckDT != null && CheckDT.Rows.Count > 0) { if (CheckDT.Rows[0]["IsAutoForRFID"].ToString() == "1") { IsTrue = false; } else { //SqlStr = @"UPDATE [T_Service_ChestPain_PatientsTimeAxis] SET [RecordingTime] = '{0}',[IsAutoForRFID] = 1 WHERE PatientGuid='{1}' and TimeAxisID='{2}' and ISNULL(IsAutoForRFID,0)=0"; SqlStr = @"exec Update_TimeAxis_RecordingTime '{1}','{2}','{0}'"; SqlStr = string.Format(SqlStr, time, patientGuid, timeAxisID); MessageAdd("更新数据 " + SqlStr); } if (sqlDBHelp.DoCom(SqlStr, config.StrCon) > 0) { IsTrue = true; } else { //开启调试模式 if (config.IsDebug) { IsTrue = false; MessageAdd(string.Format("失败:执行更新时失败,执行的SQL为:{0} {1}", SqlStr, DateTime.Now.ToString(timeToString))); } } } return IsTrue; } /// /// 更新卒中时间节点 /// /// 时间 /// 病人编码 /// 时间节点 /// private bool UpdateApoplexyTimeAxis(DateTime time, string patientGuid, string timeAxisID) { bool IsTrue = false; //先判断该病人对应的时间节点是否已经存在数据 string SqlStr = @"SELECT [ID],[RecordingTime],[IsAutoForRFID] FROM [T_Service_Apoplexy_PatientsTimeAxis] WHERE PatientGuid='{0}' and TimeAxisID='{1}' and isnull(RecordingTime,'')='' and DeleteFlag=0"; SqlStr = string.Format(SqlStr, patientGuid, timeAxisID); DataTable CheckDT = sqlDBHelp.GetDT(SqlStr, config.StrCon); if (CheckDT != null && CheckDT.Rows.Count > 0) { SqlStr = @"UPDATE [T_Service_Apoplexy_PatientsTimeAxis] SET [RecordingTime] = '{0}',[IsAutoForRFID] = 1 WHERE PatientGuid='{1}' and TimeAxisID='{2}' and ISNULL(IsAutoForRFID,0)=0"; SqlStr = string.Format(SqlStr, time, patientGuid, timeAxisID); if (sqlDBHelp.DoCom(SqlStr, config.StrCon) > 0) { IsTrue = true; } else { //开启调试模式 if (config.IsDebug) { IsTrue = false; MessageAdd(string.Format("失败:执行更新时失败,执行的SQL为:{0} {1}", SqlStr, DateTime.Now.ToString(timeToString))); } } } return IsTrue; } } }