StableVersion4.3/RFIDAutomaticInductionTime/RFIDService.cs

599 lines
24 KiB
C#

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 变量
/// <summary>
/// 同步锁
/// </summary>
private static object syncRoot = new object();
/// <summary>
/// 日志文件路径
/// </summary>
private string logPath = Application.StartupPath + @"\Log";
/// <summary>
/// 日志文件
/// </summary>
FileClass fileClass = new FileClass();
/// <summary>
/// 初始化配置文件
/// </summary>
Config config = new Config();
/// <summary>
/// 数据库访问类
/// </summary>
SqlDBHelper sqlDBHelp = new SqlDBHelper();
/// <summary>
/// 手腕带/标签卡源
/// </summary>
private DataTable labelDT = new DataTable();
/// <summary>
/// 时间格式字符
/// </summary>
private string timeToString = "yyyy-MM-dd HH:mm:ss fff";
#endregion
public RFIDService()
{
InitializeComponent();
InitService();
}
#region Windows服务私有方法
/// <summary>
/// 服务开启执行代码
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
MessageAdd(config.ServiceName + "已成功启动!");
}
/// <summary>
/// 服务结束执行代码
/// </summary>
protected override void OnStop()
{
MessageAdd(config.ServiceName + "已停止!");
}
/// <summary>
/// 服务恢复执行代码
/// </summary>
protected override void OnContinue()
{
base.OnContinue();
}
/// <summary>
/// 服务暂停执行代码
/// </summary>
protected override void OnPause()
{
base.OnPause();
}
/// <summary>
/// 系统即将关闭执行代码
/// </summary>
protected override void OnShutdown()
{
base.OnShutdown();
}
#endregion
#region 自定义方法
/// <summary>
/// 初始化服务参数
/// </summary>
private void InitService()
{
base.CanShutdown = true;
base.CanStop = true;
base.CanPauseAndContinue = true;
this.ServiceName = config.ServiceName;
this.AutoLog = false;//为了使用自定义日志,必须将 AutoLog 设置为 false
StarServer(config.StrPort);
}
/// <summary>
/// 日志记录
/// </summary>
/// <param name="serviceName">内容</param>
public void MessageAdd(string str)
{
try
{
fileClass.WriteLogFile(logPath, str);//写入记录日志
}
catch
{
}
}
#endregion
/// <summary>
/// 开启监听服务
/// </summary>
/// <param name="strPort">指定端口号</param>
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));
}
}
/// <summary>
/// 等待客户端的连接 并且创建与之通信的Socket
/// </summary>
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));
}
}
/// <summary>
/// 服务器端不停的接收客户端发来的消息
/// </summary>
/// <param name="o"></param>
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));
}
}
/// <summary>
/// 服务器向客户端发送消息
/// </summary>
/// <param name="str"></param>
private void Send(string str)
{
byte[] buffer = Encoding.Unicode.GetBytes(str);
socketSend.Send(buffer);
}
/// <summary>
/// 字节数组转16进制字符串
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 16进制字符串转字节数组 格式为 string sendMessage = "00 01 00 00 00 06 FF 05 00 64 00 00";
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 开始数据处理
/// </summary>
/// <param name="dataStr">接收的字符</param>
/// <param name="time">时间:统一各步骤时间</param>
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)));
}
}
/// <summary>
/// 判断是否是有效标签
/// </summary>
/// <param name="labelDT">标签源</param>
/// <param name="code">需要判断的标签</param>
/// <returns></returns>
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;
}
/// <summary>
/// 更新时间节点时间
/// </summary>
/// <param name="code">标签卡编号</param>
/// <param name="userCodeFlag">RFID用户码标志</param>
/// <param name="time">感应时间</param>
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)));
}
}
/// <summary>
/// 更新胸痛时间节点
/// </summary>
/// <param name="time">时间</param>
/// <param name="patientGuid">病人编码</param>
/// <param name="timeAxisID">时间节点</param>
/// <returns></returns>
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;
}
/// <summary>
/// 更新卒中时间节点
/// </summary>
/// <param name="time">时间</param>
/// <param name="patientGuid">病人编码</param>
/// <param name="timeAxisID">时间节点</param>
/// <returns></returns>
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;
}
}
}