public bool Handle(ChannelSendGroupMsgEvent <RequestIMCustomMsgSurvey> evt) { try { return(imservice.SendGroupCustomMsg(evt.ChannelID, evt.FromAccount, evt.Msg)); } catch (XuHos.Integration.QQCloudy.InvalidGroupException) { //自动修正房间不存在的问题 using (XuHos.EventBus.MQChannel mq = new MQChannel()) { var room = roomService.GetChannelInfo(evt.ChannelID); room.Enable = false; if (roomService.CompareAndSetChannelInfo(room)) { mq.Publish <XuHos.EventBus.Events.ChannelCreateEvent>(new ChannelCreateEvent() { ChannelID = evt.ChannelID, ServiceID = room.ServiceID, ServiceType = room.ServiceType, }); } return(false); } } catch (Exception Ex) { XuHos.Common.LogHelper.WriteError(Ex); return(false); } }
public bool Handle(EventBus.Events.ChannelChargingEvent evt) { try { if (evt == null) { return(true); } var room = roomService.GetChannelInfo(evt.ChannelID); #region 校验:就诊已经结束则停止计费 if (room == null || room.RoomState == EnumRoomState.AlreadyVisit) { return(true); } #endregion #region 校验:计费已经停止则停止计费 if (room.ChargingState == EnumRoomChargingState.Stoped) { return(true); } #endregion #region 校验:计费已经暂停则停止计费 if (room.ChargingState == EnumRoomChargingState.Paused) { return(true); } #endregion #region 校验:计费没有开始则停止计费 if (room.ChargingState != EnumRoomChargingState.Started) { return(true); } #endregion using (MQChannel mqChannel = new MQChannel()) { room.TotalTime += evt.Interval;//总消耗 #region 更新监控指标(记录服务时长,总耗时,就诊是否结束标志) var order = orderService.GetOrder("", room.ServiceID); if (order != null) { SysMonitorIndexService service = new SysMonitorIndexService(); var values = new Dictionary <string, string>(); values.Add("VisitingServiceChargingState", room.ChargingState.ToString()); //就诊暂停标志 values.Add("VisitingServiceDurationSeconds", room.Duration.ToString()); //就诊服务时长 values.Add("VisitingServiceElapsedSeconds", room.TotalTime.ToString()); //就诊消耗时长 values.Add("VisitingRoomState", room.RoomState.ToString()); //就诊消耗时长 if (!service.InsertAndUpdate(new RequestSysMonitorIndexUpdateDTO() { Category = "UserConsult", OutID = order.OrderNo, Values = values })) { return(false); } } #endregion //使用逻辑时间,分布式系统下存在时钟不同步问题,通过上次计费的时间增加15秒得到当前时间 var Now = evt.ChargingTime.AddSeconds(evt.Interval); room.ChargingSeq = evt.Seq; //时钟序号 room.ChargingTime = Now; //计费时间 room.ChargingInterval = evt.Interval; //时钟周期 //计费结束 if ((room.TotalTime >= room.Duration && room.Duration > 0) || (room.Duration <= 0 && room.TotalTime > 60 * 30)) { #region 计费结束 room.RoomState = XuHos.Common.Enum.EnumRoomState.AlreadyVisit; room.EndTime = Now;//这里使用逻辑时间(不要使用系统时间) if (roomService.CompareAndSetChannelInfo(room)) { var DoctorUid = roomService.GetChannelUsersInfo(room.ChannelID).FirstOrDefault(a => a.UserType == EnumUserType.Doctor); if (DoctorUid == null) { return(false); } else { #region 更新订单状态 if (room.ServiceType == EnumDoctorServiceType.AudServiceType || room.ServiceType == EnumDoctorServiceType.VidServiceType || room.ServiceType == EnumDoctorServiceType.PicServiceType || room.ServiceType == EnumDoctorServiceType.Consultation) { //订单完成 if (!orderService.Complete("", room.ServiceID)) { return(false); } } #endregion //语音、视频看诊 if (room.ServiceType == EnumDoctorServiceType.AudServiceType || room.ServiceType == EnumDoctorServiceType.VidServiceType) { #region 发送频道房间挂断消息 if (!imService.SendGroupCustomMsg(evt.ChannelID, DoctorUid.identifier, new BLL.Sys.DTOs.Request.RequestIMCustomMsgRoomTurnOff() { Data = new RequestConversationRoomStatusDTO() { ChannelID = room.ChannelID, Duration = room.Duration, ServiceID = room.ServiceID, ServiceType = room.ServiceType, State = room.RoomState, TotalTime = room.TotalTime, DisableWebSdkInteroperability = room.DisableWebSdkInteroperability, }, Desc = "本次就诊已结束" })) { return(false); } #endregion } return(true); } } #endregion } //不限制时长,会长期占用服务端资源。现在计费之前都会设置默认时长。在没有设置默认时长的时候则是小于0的数据 else if (room.Duration <= 0) { #region 计费中 if (roomService.CompareAndSetChannelInfo(room)) { //发布延时消息,15秒为一个周期。消费端收到消息后重新计算房间已通话时间。 return(mqChannel.Publish <EventBus.Events.ChannelChargingEvent>(new EventBus.Events.ChannelChargingEvent() { ChannelID = evt.ChannelID, Seq = evt.Seq + 1, ChargingTime = Now, Interval = evt.Interval }, evt.Interval)); } else { return(false); } #endregion } //计费未结束,继续计费 else if (room.TotalTime < room.Duration) { #region 计费中 if (roomService.CompareAndSetChannelInfo(room)) { var Interval = room.Duration - room.TotalTime; mqChannel.BeginTransaction(); #region 检查:是否需要发送续费消息.接近一分钟时发送 var Duration = (room.Duration <= 0 ? 0 : room.Duration); var TotalTime = room.TotalTime > Duration ? Duration : room.TotalTime; if (room.ChargingSeq == (room.Duration / room.ChargingInterval) - (60 / room.ChargingInterval)) { //获取患者信息 var otherUser = roomService.GetChannelUsersInfo(room.ChannelID).Where(a => a.UserType != EnumUserType.Doctor); #region 药店不需要发送续费消息 if (!otherUser.Any(a => a.UserType == EnumUserType.Drugstore)) { if (!mqChannel.Publish <EventBus.Events.ChannelExpireEvent>(new EventBus.Events.ChannelExpireEvent() { ServiceID = room.ServiceID })) { return(false); } } #endregion } #endregion //剩余时间大于一个时钟周期,那么按照正常时钟15秒处理 if (Interval > evt.Interval) { //发布延时消息,15秒为一个周期。消费端收到消息后重新计算房间已通话时间。 if (!mqChannel.Publish <EventBus.Events.ChannelChargingEvent>(new EventBus.Events.ChannelChargingEvent() { ChannelID = evt.ChannelID, Seq = evt.Seq + 1, ChargingTime = Now, Interval = evt.Interval }, evt.Interval)) { return(false); } } //如果小于小于时钟周期那么,按照剩余时间执行 else { //发布延时消息,15秒为一个周期。消费端收到消息后重新计算房间已通话时间。 if (!mqChannel.Publish <EventBus.Events.ChannelChargingEvent>(new EventBus.Events.ChannelChargingEvent() { ChannelID = evt.ChannelID, Seq = evt.Seq + 1, ChargingTime = Now, Interval = evt.Interval }, evt.Interval)) { return(false); } } mqChannel.Commit(); return(true); } else { return(false); } #endregion } } } catch (Exception ex) { XuHos.Common.LogHelper.WriteError(ex); } return(false); }
public bool Handle(EventBus.Events.ChannelStateChangedEvent evt) { DTO.ConversationRoomDTO room = null; try { if (evt == null) { return(true); } if (string.IsNullOrEmpty(evt.FromUserID)) { return(true); } //获取房间信息 room = roomService.GetChannelInfo(evt.ChannelID); #region 参数校验:房间不存在的则不允许修改 if (room == null) { return(true); } #endregion var userInfo = userService.GetUserInfoByUserId(evt.FromUserID); var CurrentOperatorUserIdentifier = userInfo.identifier; var RoomStateChangeMsgDesc = ""; var RoomOperatorType = ""; var RoomOperatorRemark = ""; //结束看诊 if (evt.State == EnumRoomState.AlreadyVisit) { if (userInfo.UserType == EnumUserType.Doctor) { #region 停止计费 if (room.ChargingState == EnumRoomChargingState.Started && !roomService.PauseCharging(evt.ChannelID)) { return(false); } #endregion #region 更新订单状态 if (room.ServiceType == EnumDoctorServiceType.AudServiceType || room.ServiceType == EnumDoctorServiceType.VidServiceType || room.ServiceType == EnumDoctorServiceType.PicServiceType || room.ServiceType == EnumDoctorServiceType.Consultation) { //订单完成 if (!orderService.Complete("", room.ServiceID)) { XuHos.Common.LogHelper.WriteWarn($"订单完成失败,ServiceID={room.ServiceID}"); return(false); } } #endregion #region 更新监控指标(记录服务时长,总耗时,就诊是否结束标志) var order = orderService.GetOrder("", room.ServiceID); if (order != null) { SysMonitorIndexService service = new SysMonitorIndexService(); var values = new Dictionary <string, string>(); values.Add("VisitingServiceChargingState", room.ChargingState.ToString()); //就诊暂停标志 values.Add("VisitingServiceDurationSeconds", room.Duration.ToString()); //就诊服务时长 values.Add("VisitingServiceElapsedSeconds", room.TotalTime.ToString()); //就诊消耗时长 values.Add("VisitingRoomState", room.RoomState.ToString()); //就诊暂停标志 if (!service.InsertAndUpdate(new RequestSysMonitorIndexUpdateDTO() { Category = "UserConsult", OutID = order.OrderNo, Values = values })) { return(false); } } #endregion //语音、视频看诊 if (room.ServiceType == EnumDoctorServiceType.AudServiceType || room.ServiceType == EnumDoctorServiceType.VidServiceType) { var DoctorID = ""; #region 获取医生编号 if (room.ServiceType == EnumDoctorServiceType.AudServiceType || room.ServiceType == EnumDoctorServiceType.VidServiceType) { BLL.UserOPDRegisterService bllOPD = new UserOPDRegisterService(""); //获取预约信息 var opd = bllOPD.Single <UserOPDRegister>(room.ServiceID); if (opd != null) { DoctorID = opd.DoctorID; } else { XuHos.Common.LogHelper.WriteWarn("房间 " + room.ChannelID + " 对应的预约记录不存在"); } } #endregion var DoctorUid = uidService.GetDoctorIMUid(DoctorID); #region 发送候诊队列通知 roomService.SendWaitingQueueChangeNotice(DoctorID); #endregion } RoomOperatorRemark = $""; RoomOperatorType = "Hangup"; RoomStateChangeMsgDesc = "医生已结束看诊,请对本次服务作出评价"; } else { //无效请求 return(true); } } else if (evt.State == EnumRoomState.Waiting) { //取消呼叫 if (userInfo.UserType == EnumUserType.Doctor) { RoomStateChangeMsgDesc = "医生取消了呼叫"; RoomOperatorType = "Call_Cancel"; } else { RoomStateChangeMsgDesc = "患者正在候诊,等待医生呼叫"; RoomOperatorType = "Wait"; #region 修改状态并设置分诊编号 room.RoomState = evt.State; room.TriageID = XuHos.Common.Utility.SeqIDHelper.GetSeqId(); //修改就诊时间和开始就诊时间 if (!roomService.CompareAndSetChannelInfo(room)) { XuHos.Common.LogHelper.WriteWarn($"修改房间信息失败,ChannelID={room.ChannelID}"); return(false); } #endregion #region 发送患者进入诊室的通知 if (userInfo.UserType == EnumUserType.User || userInfo.UserType == EnumUserType.Drugstore) { using (XuHos.EventBus.MQChannel mqChannel = new MQChannel()) { if (!mqChannel.Publish <EventBus.Events.UserNoticeEvent>(new EventBus.Events.UserNoticeEvent() { NoticeType = EnumNoticeSecondType.DoctorVidUserEnterRoomNotice, ServiceID = room.ServiceID })) { XuHos.Common.LogHelper.WriteWarn($"Publis UserNoticeEvent失败,ServiceID={room.ServiceID}"); return(false); } } } #endregion } } else if (evt.State == EnumRoomState.Calling) { //医生呼叫患者 if (userInfo.UserType == EnumUserType.Doctor) { RoomOperatorType = "Calling"; RoomStateChangeMsgDesc = "医生正在呼叫,等待患者接听"; using (XuHos.EventBus.MQChannel mqChannel = new MQChannel()) { if (!mqChannel.Publish <EventBus.Events.UserNoticeEvent>(new EventBus.Events.UserNoticeEvent() { NoticeType = EnumNoticeSecondType.UserVidDoctorCallNotice, ServiceID = room.ServiceID })) { return(false); } } } else { //无效请求 return(true); } } else if (evt.State == EnumRoomState.InMedicalTreatment) { if (userInfo.UserType == EnumUserType.Doctor) { //无效请求 return(true); } //患者接听 else { RoomOperatorType = "Calling_Answer"; RoomStateChangeMsgDesc = "患者已进入诊室"; #region 修改订单状态,用户将不能够再取消订单 if (room.ServiceType == EnumDoctorServiceType.AudServiceType || room.ServiceType == EnumDoctorServiceType.VidServiceType) { #region 语音/视频 修改订单状态(配送中) if (!orderService.LogisticWithDistributionIn(room.ServiceID)) { return(false); } #endregion } else if (room.ServiceType == EnumDoctorServiceType.PicServiceType) { #region 图文咨询 修改订单状态(配送中) BLL.OrderService bllOrder = new OrderService(evt.FromUserID); if (!bllOrder.LogisticWithDistributionIn(room.ServiceID)) { return(false); } #endregion } #endregion #region 计算候诊耗时并更新统计指标 var log = roomService.GetChannelLastLog(room.ConversationRoomID, "Wait"); var order = orderService.GetOrder("", room.ServiceID); if (log != null && order != null) { //候诊耗时 var WaitingElapsedSeconds = (DateTime.Now - log.OperationTime).TotalSeconds; RoomOperatorRemark = $"用户候诊用时{WaitingElapsedSeconds}秒"; SysMonitorIndexService service = new SysMonitorIndexService(); var values = new Dictionary <string, string>(); values.Add("WaitingElapsedSeconds", WaitingElapsedSeconds.ToString()); //更新候诊总耗时,指标=原指标+新指标 if (!service.InsertAndUpdate(new RequestSysMonitorIndexUpdateDTO() { Category = "UserConsult", OutID = order.OrderNo, Values = values }, true)) { return(false); } } #endregion } } else if (evt.State == EnumRoomState.NoTreatment) { if (userInfo.UserType == EnumUserType.Doctor) { RoomOperatorType = "Calling_Cancel"; RoomStateChangeMsgDesc = "医生取消了呼叫"; } else { RoomOperatorType = "Waiting_Cancel"; RoomStateChangeMsgDesc = "患者取消了候诊"; } //发送指令前状态是在就诊中 if (evt.ExpectedState == EnumRoomState.InMedicalTreatment) { #region 停止计费 if (room.ChargingState == EnumRoomChargingState.Started && !roomService.PauseCharging(evt.ChannelID)) { return(false); } #endregion } } else if (evt.State == EnumRoomState.Disconnection) { if (userInfo.UserType == EnumUserType.Doctor) { RoomOperatorType = "Leave"; RoomStateChangeMsgDesc = "医生已离开"; } else { RoomOperatorType = "Leave"; RoomStateChangeMsgDesc = "患者已离开"; } #region 停止计费 if (room.ChargingState == EnumRoomChargingState.Started && !roomService.PauseCharging(evt.ChannelID)) { return(false); } #endregion } else if (evt.State == EnumRoomState.WaitAgain) { RoomOperatorType = "Waiting"; RoomStateChangeMsgDesc = "患者正在候诊,等待医生呼叫"; } if (room.Enable) { var State = room.RoomState; //兼容移动端状态 if (State == EnumRoomState.WaitAgain) { State = EnumRoomState.Waiting; } ///写入日志 if (!roomService.InsertChannelLog(room.ConversationRoomID, userInfo.UserID, userInfo.UserCNName, RoomOperatorType, RoomStateChangeMsgDesc, RoomOperatorRemark)) { return(false); } if (!imService.SendGroupCustomMsg(evt.ChannelID, CurrentOperatorUserIdentifier, new BLL.Sys.DTOs.Request.RequestCustomMsgRoomStateChanged() { Data = new RequestConversationRoomStatusDTO() { ChannelID = evt.ChannelID, State = State, ServiceID = room.ServiceID, ServiceType = room.ServiceType, Duration = room.Duration, ChargingState = room.ChargingState, TotalTime = room.TotalTime, DisableWebSdkInteroperability = room.DisableWebSdkInteroperability }, Desc = RoomStateChangeMsgDesc })) { return(false); } } } catch (XuHos.Integration.QQCloudy.InvalidGroupException) { if (room != null) { room.Enable = false; if (roomService.CompareAndSetChannelInfo(room)) { new XuHos.Service.EventHandlers.ChanneCreateEvent.DefaultHandler().Handle(new EventBus.Events.ChannelCreateEvent() { ChannelID = evt.ChannelID, ServiceID = room.ServiceID, ServiceType = room.ServiceType }); } } return(false); } catch (Exception E) { LogHelper.WriteError(E); return(false); } return(true); }