Files
Web_CRICS_Server_VS2010_Prod/RCUHost/Implement/ServiceReceiver.cs

399 lines
15 KiB
C#
Raw Normal View History

2025-12-11 09:17:16 +08:00
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Common;
using Dao;
using Domain;
using RCUHost.Protocols;
namespace RCUHost.Implement
{
public class ServiceReceiver : GenericReceiverBase, IServiceReceiver
{
private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(ServiceReceiver));
private ConcurrentDictionary<string, ConcurrentDictionary<int, ServiceStatus>> roomsServices = new ConcurrentDictionary<string, ConcurrentDictionary<int, ServiceStatus>>();
public IHostRepository HostRepository { get; set; }
public IAlarmSettingRepository AlarmSettingRepository { get; set; }
public IRoomServiceRepository RoomServiceRepository { get; set; }
public IRoomServiceRecordRepository RoomServiceRecordRepository { get; set; }
public void SetService(Host host, int serviceCode, int status)
{
byte[] data = CreateServiceControlDataPacket(serviceCode, status);
SendAndPushCommandQueue(data, host.HostNumber, host.MAC);// host.IP, host.Port);
}
public override void Process(ReceiverContext context)
{
bool bkb = GenericReceiverBase.DealWwith(context);
if (bkb == false)
{
return;
}
Reply(context);
Host host = HostRepository.GetByHostNumber(context.SystemHeader.Value.HostNumber.ToString());//.RemoteEndPoint.Address.ToString());
if (host != null)
{
try
{
int offset = StructConverter.SizeOf(context.SystemHeader);
int length = context.Data.Length - offset - 2;
using (MemoryStream stream = new MemoryStream(context.Data, offset, length))
{
var services = DecodeServices(host.IP, stream);
foreach (var service in services)
{
if (service.Value.Status != 2)
{
//处理服务
ProcessServices(host, service.Value);
//设置Host表的保险箱状态
if (service.Value.Code == 12)
{
HostRepository.SetSafeBoxStatus(host, service.Value.Status);
}
//处理异常
ProcessAbnormities(host, service.Value);
}
}
}
}
catch (Exception ex)
{
if (logger.IsErrorEnabled)
{
logger.Error(context.RemoteEndPoint.Address.ToString() + ":" + context.RemoteEndPoint.Port.ToString() + ":" + Tools.ByteToString(context.Data));
logger.Error("解析【" + host.HostNumber + "】客房服务数据出错。", ex);
}
}
}
}
/// <summary>
/// 处理服务
/// </summary>
/// <param name="host"></param>
/// <param name="status"></param>
private void ProcessServices(Host host, ServiceStatus status)
{
var serviceSetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'B', status.Code);
if (serviceSetting != null && status.Status != 2)
{
//更新客房服务状态
var roomService = RoomServiceRepository.Get(host.ID, serviceSetting.Code);
if (roomService != null && roomService.Status != Convert.ToBoolean(status.Status))
{
roomService.Status = Convert.ToBoolean(status.Status);
roomService.StartTime = DateTime.Now;
RoomServiceRepository.Update(roomService);
}
if (status.Status == 0)
{
//更新清除服务记录状态和时间
var serviceRecord = RoomServiceRecordRepository.Get(host.ID, serviceSetting.Code, true);
if (serviceRecord != null)
{
serviceRecord.Status = false;
serviceRecord.EndTime = DateTime.Now;
RoomServiceRecordRepository.Update(serviceRecord);
}
}
else if (status.Status == 1)
{
//判断数据库中是否存在服务开启记录,不存在才去记录服务
var existServiceRecord = RoomServiceRecordRepository.Get(host.ID, serviceSetting.Code, true);
if (existServiceRecord == null)
{
var serviceRecord = new RoomServiceRecord();
serviceRecord.HostID = host.ID;
serviceRecord.RoomNumber = host.RoomNumber;
serviceRecord.AlarmCode = serviceSetting.Code;
serviceRecord.Name = serviceSetting.Name;
serviceRecord.Status = true;
serviceRecord.StartTime = DateTime.Now;
RoomServiceRecordRepository.Save(serviceRecord);
}
}
//给FreeGo福瑞狗上报服务状态
//FreeGoOperation.UploadService(host.SysHotel.Code, host.RoomNumber, serviceSetting.Name, status.Status.ToString());
}
}
/// <summary>
/// 处理异常
/// </summary>
/// <param name="host"></param>
/// <param name="status"></param>
private void ProcessAbnormities(Host host, ServiceStatus status)
{
#region
var abnormitySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C03", status.Code);
if (abnormitySetting != null)
{
var abnormity = RoomServiceRepository.Get(host.ID, abnormitySetting.Code);
bool isUpdated = false;
if (status.Status == 1)
{
//保险箱开 如果非客人卡且出租房态,则报警
if (host.RoomCard != null && host.RoomCard.RoomCardType != null && host.RoomCard.RoomCardType.ID != 0x20 &&
host.RoomStatus != null && host.RoomStatus.ID == 0x02)
{
isUpdated = true;
if (abnormity != null && !abnormity.Status)
{
abnormity.Status = true;
abnormity.StartTime = DateTime.Now;
RoomServiceRepository.Update(abnormity);
//插入保险箱开的记录
var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, abnormitySetting.Code, true);
if (abnormityRecord == null)
{
abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormitySetting);
RoomServiceRecordRepository.Save(abnormityRecord);
}
}
}
}
//保险箱关或未接保险箱(关掉报警)
if (!isUpdated)
{
if (abnormity != null && abnormity.Status)
{
abnormity.Status = false;//取消报警
abnormity.StartTime = DateTime.Now;
RoomServiceRepository.Update(abnormity);
//更新保险箱关的记录
var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, abnormitySetting.Code, true);
if (abnormityRecord != null)
{
abnormityRecord.Status = false;
abnormityRecord.EndTime = DateTime.Now;
RoomServiceRecordRepository.Update(abnormityRecord);
}
}
}
}
#endregion
#region 退
abnormitySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C04", status.Code);
var abnormity1 = RoomServiceRepository.Get(host.ID, "C04");
if (abnormitySetting != null && abnormity1 != null)
{
bool isUpdated = false;
if (status.Status == 0)
{
//保险箱关 如果是“退房”状态,则报警
if (host.RoomStatus != null && host.RoomStatus.ID == 0x08)
{
isUpdated = true;
if (!abnormity1.Status)
{
abnormity1.Status = true;
abnormity1.StartTime = DateTime.Now;
RoomServiceRepository.Update(abnormity1);
//异常记录
var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, abnormitySetting.Code, true);
if (abnormityRecord == null)
{
abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormitySetting);
RoomServiceRecordRepository.Save(abnormityRecord);
}
}
}
}
if (!isUpdated)
{
//保险箱开或未接保险箱(关掉报警)
if (abnormity1.Status)
{
abnormity1.Status = false;
abnormity1.StartTime = DateTime.Now;
RoomServiceRepository.Update(abnormity1);
//异常记录
var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, abnormitySetting.Code, true);
if (abnormityRecord != null)
{
abnormityRecord.Status = false;
abnormityRecord.EndTime = DateTime.Now;
RoomServiceRecordRepository.Update(abnormityRecord);
}
}
}
}
#endregion
}
/// <summary>
/// 创建服务控制数据包
/// </summary>
/// <param name="devices"></param>
/// <returns></returns>
public byte[] CreateServiceControlDataPacket(int serviceCode, int status)
{
using (MemoryStream buffer = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(buffer))
{
var headerLen = StructConverter.SizeOf(typeof(SystemHeader));
buffer.Seek(headerLen, SeekOrigin.Begin);
writer.Write((byte)1); //写入服务数量
writer.Write((byte)serviceCode); //写入服务代码
writer.Write((byte)status); //写入服务状态
writer.Write(new byte[] { 0, 0 }, 0, 2);//预留两字节CRC16校验码
buffer.Seek(0, SeekOrigin.Begin);
var header = CreateSystemHeader((int)buffer.Length - headerLen);
var headerData = StructConverter.StructToBytes(header);
writer.Write(headerData, 0, headerData.Length);
return buffer.ToArray();
}
}
}
public override CommandType CommandType
{
get { return CommandType.Service; }
}
/// <summary>
/// 解析服务状态
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
private ConcurrentDictionary<int, ServiceStatus> DecodeServices(string hostIP, Stream stream)
{
ConcurrentDictionary<int, ServiceStatus> services = null;
if (roomsServices.ContainsKey(hostIP))
{
services = roomsServices[hostIP];
}
else
{
services = new ConcurrentDictionary<int, ServiceStatus>();
roomsServices[hostIP] = services;
}
using (BinaryReader reader = new BinaryReader(stream))
{
try
{
int count = reader.ReadByte();//读取服务数量
for (int i = 0; i < count; i++)
{
ServiceStatus serviceStatus = null;
int serviceCode = reader.ReadByte();//读取服务代码
if (services.ContainsKey(serviceCode))
{
serviceStatus = services[serviceCode];
}
else
{
serviceStatus = new ServiceStatus();
services[serviceCode] = serviceStatus;
}
serviceStatus.Code = serviceCode;
serviceStatus.Status = reader.ReadByte();//读取服务状态
}
}
catch (Exception) { }
return services;
}
}
}
internal class ServiceStatus
{
private int code;
private int status = 2;
public int Code
{
get { return this.code; }
set
{
this.code = value;
}
}
public int Status
{
get { return this.status; }
set
{
this.status = value;
}
}
}
internal delegate void ServiceChangedDelegate(string hostIP, ServiceStatus serviceStatus);
internal class RoomServiceCache
{
private Hashtable services = new Hashtable();
public string HostIP { get; set; }
public event ServiceChangedDelegate ServiceChanged;
public void AddOrUpdate(int code, int status)
{
ServiceStatus service = services[code] as ServiceStatus;
if (service != null)
{
if (service.Status != status)
{
service.Status = status;
RasieServiceChanged(service);
}
}
else
{
service = new ServiceStatus();
service.Code = code;
service.Status = status;
services[code] = service;
RasieServiceChanged(service);
}
}
public IList<ServiceStatus> Services
{
get
{
IList<ServiceStatus> values = new List<ServiceStatus>();
foreach (var service in services.Values)
{
values.Add((ServiceStatus)service);
}
return values;
}
}
private void RasieServiceChanged(ServiceStatus serviceStatus)
{
if (ServiceChanged != null)
{
ServiceChanged(HostIP, serviceStatus);
}
}
}
}