using WingInterfaceLibrary.LiveConsultation;
using WingInterfaceLibrary.Enum;
using WingInterfaceLibrary.Request.Notification;
using WingServerCommon.Config;
using WingInterfaceLibrary.Notifications;
using WingServerCommon.Interfaces.Cache;
using WingInterfaceLibrary.Rtc;
using WingServerCommon.Log;
using System.Text;
using WingInterfaceLibrary.DTO.User;
using WingInterfaceLibrary.LiveConsultation.Consultation;
namespace WingLiveConsultationService
{
///
/// 会诊房间
///
public partial class LiveConsultationRoom : LiveConsultationRoomDTO
{
public static Func OnRtcGenerateRoomUrl;
public static Func OnGetUserSign;
public LiveConsultationRoom(string roomId, int roomNo, string patientName, DateTime consultationTime, TransactionStatusEnum consultationStatus
, string applyOrganizationCode, string applyUserCode, string expertOrganizationCode, List liveMembers, string expertUserCode, bool isEmergency) : base(roomId)
{
RoomId = roomId;
RoomNo = roomNo;
PatientName = patientName ?? string.Empty;
ConsultationTime = consultationTime;
ConsultationStatus = consultationStatus;
ApplyOrganizationCode = applyOrganizationCode;
ApplyUserCode = applyUserCode;
ExpertOrganizationCode = expertOrganizationCode;
Members = liveMembers ?? new List();
ExpertUserCode = expertUserCode;
IsEmergency = isEmergency;
InteractiveBoardDatas = new List();
}
///
/// 修改预约记录状态
///
///
public void ChangeConsultationStatus(TransactionStatusEnum status)
{
WriteDebugLogs("ChangeConsultationStatus", null, $"{ConsultationStatus.ToString()}>>{status.ToString()}");
ConsultationStatus = status;
}
///
/// 参与人员同意参加会诊
///
///
public void Agree(string userCode)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null)
{
liveMember.Status = LiveConsultationMemberStatus.Default;
}
else
{
liveMember = InitLiveMemberByCode(userCode);
liveMember.Status = LiveConsultationMemberStatus.Default;
Members.Add(liveMember);
}
WriteDebugLogs("Agree", liveMember);
}
///
/// 开始会诊
///
///
///
///
///
public void Initiate(string initiatorCode, int integerRoomId, int timeout, int sdkAppId, bool pushMessage = false)
{
var initiator = Members.FirstOrDefault(x => x.Id == initiatorCode);
if (initiator != null)
{
initiator.IsInitiator = true;
initiator.Status = LiveConsultationMemberStatus.Joined;
}
else
{
initiator = InitLiveMemberByCode(initiatorCode);
initiator.IsInitiator = true;
initiator.Status = LiveConsultationMemberStatus.Joined;
Members.Add(initiator);
}
foreach (var liveMember in Members)
{
if (liveMember.Id != initiatorCode)
{
liveMember.IsInitiator = false;
liveMember.Status = LiveConsultationMemberStatus.Default;
}
liveMember.Mute = false;
liveMember.VideoOpend = true;
liveMember.IsControllingParameter = false;
}
RoomNo = integerRoomId;
ConsultationStatus = TransactionStatusEnum.InProgress;
Status = LiveConsultationRoomStatus.Initiating;
InteractiveBoardDatas = new List();
EmergencyAccepted = false;
RefreshMemberInfosByToken();
//StartCheckConnectionTimeout(timeout);
if (pushMessage)
{
PushInitiateMessage(sdkAppId);
}
WriteDebugLogs("Initiate", initiator);
}
///
/// 接受会诊邀请-参与人员
///
///
public void Accept(string userCode, bool pushMessage = false)
{
var accepter = Members.FirstOrDefault(x => x.Id == userCode);
if (accepter != null)
{
accepter.Status = LiveConsultationMemberStatus.Accepted;
accepter.Mute = false;
accepter.IsControllingParameter = false;
accepter.VideoOpend = true;
RemoveInteractiveBoardDatasByUserCode(userCode);
if (Status == LiveConsultationRoomStatus.Connected)
{
Status = LiveConsultationRoomStatus.Initiating;
}
if (pushMessage)
{
PushCancelInviteInMessage(new List { accepter.Id }, true);//取消其他端的呼叫行为
PushAcceptMessage(accepter);
}
}
WriteDebugLogs("Accept", accepter);
}
///
/// 接受会诊邀请-急诊专家
///
///
///
///
public void EmergencyAccept(string userCode, string orgCode, bool pushMessage = false)
{
EmergencyAccepted = true;
var accepter = Members.FirstOrDefault(x => x.Id == userCode);
if (accepter == null)
{
accepter = InitLiveMemberByCode(userCode);
accepter.Status = LiveConsultationMemberStatus.Accepted;
Members.Add(accepter);
//急诊专家信息
ExpertUserCode = userCode;
ExpertOrganizationCode = orgCode;
}
accepter.Status = LiveConsultationMemberStatus.Accepted;
accepter.Mute = false;
accepter.VideoOpend = true;
accepter.IsControllingParameter = false;
if (Status == LiveConsultationRoomStatus.Connected)
{
Status = LiveConsultationRoomStatus.Initiating;
}
if (pushMessage)
{
PushAcceptMessage(accepter);
}
WriteDebugLogs("EmergencyAccept", accepter);
}
///
/// 拒绝会诊邀请-参与人员
///
///
public void Reject(string userCode, bool pushMessage = false)
{
var rejecter = Members.FirstOrDefault(x => x.Id == userCode);
if (rejecter != null)
{
rejecter.Status = LiveConsultationMemberStatus.Rejected;
if (pushMessage)
{
PushCancelInviteInMessage(new List { rejecter.Id }, true);//取消其他端的呼叫行为
PushRejectMessage(rejecter);
}
}
WriteDebugLogs("Reject", rejecter);
}
///
/// 取消会诊
///
public void CancelInitiate(bool pushMessage = false)
{
Status = LiveConsultationRoomStatus.Cancelled;
ConsultationStatus = TransactionStatusEnum.ToStart;
if (pushMessage)
{
PushCancelMessage();
PushCloseMessage();
}
foreach (var liveMember in Members)
{
if (liveMember.Status == LiveConsultationMemberStatus.Joined)
{
liveMember.Status = LiveConsultationMemberStatus.Left;
}
}
WriteDebugLogs("CancelInitiate", Initiator);
}
///
/// 会诊心跳,进入房间
///
///
public void HeartRateJoin(string userCode, bool pushMessage = false)
{
var joiner = Members.FirstOrDefault(x => x.Id == userCode);
if (joiner != null && joiner.Status != LiveConsultationMemberStatus.Joined)
{
joiner.Status = LiveConsultationMemberStatus.Joined;
if (pushMessage)
{
PushHeartRateJoinMessage(joiner);
}
}
WriteDebugLogs("HeartRateJoin", joiner);
}
///
/// 会诊心跳,网络质量不佳
///
///
public void NetworkErr(string userCode, bool pushMessage = false)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
{
if (pushMessage)
{
PushNetworkErrMessage(liveMember);
}
}
WriteDebugLogs("NetworkErr", liveMember);
}
///
/// 会诊心跳,离开房间
///
///
public bool HeartRateLeave(string userCode, bool pushMessage = false)
{
var leaver = Members.FirstOrDefault(x => x.Id == userCode);
var needClose = false;
if (leaver != null && leaver.Status == LiveConsultationMemberStatus.Joined)
{
leaver.Status = LiveConsultationMemberStatus.Left;
if (pushMessage)
{
PushHeartRateLeaveMessage(leaver);
}
if (MainUserInfos == null || MainUserInfos.All(x => x.Status != LiveConsultationMemberStatus.Joined))
{
Close(pushMessage);
needClose = true;
}
}
WriteDebugLogs("HeartRateLeave", leaver);
return needClose;
}
///
/// 离开房间,含结束会诊
///
///
public bool Leave(string userCode, bool pushMessage = false)
{
var leaver = Members.FirstOrDefault(x => x.Id == userCode);
var needClose = false;
if (leaver != null && leaver.Status == LiveConsultationMemberStatus.Joined)
{
leaver.Status = LiveConsultationMemberStatus.Left;
leaver.Mute = false;
leaver.IsControllingParameter = false;
leaver.VideoOpend = true;
RemoveInteractiveBoardDatasByUserCode(userCode);
if (pushMessage)
{
PushLeaveMessage(leaver);
}
if (MainUserInfos == null || MainUserInfos.All(x => x.Status != LiveConsultationMemberStatus.Joined))
{
Close(pushMessage);
needClose = true;
}
}
WriteDebugLogs("Leave", leaver, $"close:{needClose.ToString()}");
return needClose;
}
///
/// 结束会诊
///
public void Close(bool pushMessage = false)
{
Status = LiveConsultationRoomStatus.Closed;
ConsultationStatus = TransactionStatusEnum.PendingReport;
if (pushMessage)
{
PushCancelMessage();
PushCloseMessage();
}
foreach (var liveMember in Members)
{
if (liveMember.Status == LiveConsultationMemberStatus.Joined)
{
liveMember.Status = LiveConsultationMemberStatus.Left;
}
}
InteractiveBoardDatas = new List();
WriteDebugLogs("Close");
}
///
/// 开启关闭静音
///
///
///
public void ChangeMuteState(string userCode, bool mute, bool pushMessage = false)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
{
liveMember.Mute = mute;
if (pushMessage)
{
PushMuteStateMessage(liveMember);
}
}
WriteDebugLogs("ChangeMuteState", liveMember, $"mute:{mute.ToString()}");
}
///
/// 开启关闭视频
///
///
///
public void ChangeVideoOpenState(string userCode, bool isVideoOpen, bool pushMessage = false)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
{
liveMember.VideoOpend = isVideoOpen;
if (pushMessage)
{
PushVideoOpenStateMessage(liveMember);
}
}
WriteDebugLogs("ChangeVideoOpenState", liveMember, $"isVideoOpen:{isVideoOpen.ToString()}");
}
///
/// 更改调参状态
///
///
///
public void ChangeControllingParameterState(string userCode, bool isControllingParameter)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
{
liveMember.IsControllingParameter = isControllingParameter;
}
WriteDebugLogs("ChangeControllingParameterState", liveMember, $"isControllingParameter:{isControllingParameter.ToString()}");
}
///
/// 会诊中邀请
///
///
///
public void InviteIn(string userCode, List clientIds, bool pushMessage = false)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
{
if (pushMessage)
{
PushInviteInMessage(liveMember, clientIds);
}
}
WriteDebugLogs("InviteIn", liveMember);
}
///
/// 取消会诊中邀请
///
///
///
public void CancelInviteIn(string userCode, List clientIds, bool pushMessage = false)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
{
var notifyUserCodes = new List();
foreach (var clientId in clientIds)
{
if (Members.Any(x => x.Id == clientId && x.Status == LiveConsultationMemberStatus.Joined))
{
continue;
}
notifyUserCodes.Add(clientId);
}
if (notifyUserCodes.Any())
{
if (pushMessage)
{
PushCancelInviteInMessage(notifyUserCodes);
}
}
}
WriteDebugLogs("CancelInviteIn", liveMember);
}
///
/// 接受会诊中邀请
///
///
public void AcceptIn(string userCode, bool pushMessage = false)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null)
{
liveMember.Status = LiveConsultationMemberStatus.Accepted;
liveMember.Mute = false;
liveMember.IsControllingParameter = false;
liveMember.VideoOpend = true;
}
else
{
liveMember = InitLiveMemberByCode(userCode);
liveMember.Status = LiveConsultationMemberStatus.Accepted;
liveMember.Mute = false;
liveMember.IsControllingParameter = false;
liveMember.VideoOpend = true;
Members.Add(liveMember);
}
RemoveInteractiveBoardDatasByUserCode(userCode);
if (pushMessage)
{
PushCancelInviteInMessage(new List { liveMember.Id }, true);//取消其他端的呼叫行为
PushAcceptInMessage(liveMember);
}
WriteDebugLogs("AcceptIn", liveMember);
}
///
/// 拒绝会诊中邀请
///
///
public void RejectIn(string rejecterCode, bool pushMessage = false)
{
if (Initiator != null && Initiator.Status == LiveConsultationMemberStatus.Joined)
{
var userInfo = CacheMaintenance.Instance.Get().Get(rejecterCode);
WriteDebugLogs("RejectIn", Initiator, $"rejecter name:{userInfo.UserName};{userInfo.FullName}");
if (pushMessage)
{
PushCancelInviteInMessage(new List { userInfo.Code }, true);//取消其他端的呼叫行为
PushRejectInMessage(Initiator, userInfo);
}
}
else
{
WriteDebugLogs("RejectIn", Initiator);
}
}
///
/// 发送白板交互数据
///
///
///
///
public void SendBoardData(string userCode, string boardData, DateTime interactiveTime, bool isClear, bool pushMessage = false)
{
var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
{
if (!isClear)
{
InteractiveBoardDatas.Add(new InteractiveBoardDataDTO
{
InteractiveTime = interactiveTime,
UserCode = userCode,
BoardData = boardData,
});
}
else
{
RemoveInteractiveBoardDatasByUserCode(userCode);
}
if (pushMessage)
{
PushBoardDataMessage(liveMember, boardData, isClear);
}
}
WriteDebugLogs("SendBoardData", liveMember);
}
///
/// 呼叫急诊专家
///
///
///
public void CallEmergencyDoctor(UserDTO doctor, int timeOut)
{
if (!EmergencyAccepted)
{
PushEmergencyMessage(doctor, timeOut);
}
}
///
/// 急诊呼叫失败
///
public void EmergencyFailed()
{
if (!EmergencyAccepted)
{
PushEmergencyFailedMessage();
}
}
///
/// 切换会诊房间
///
///
///
///
///
///
public void ChangeRoom(string userCode, LiveConsultationRoom current, int timeout, int sdkAppId)
{
current.Initiate(Initiator.Id, RoomNo, timeout, sdkAppId, false);
var closeMemberCodes = new List();
foreach (var origMember in Members)
{
if (origMember.Status != LiveConsultationMemberStatus.Joined)
{
continue;
}
var liveMember = current.Members.FirstOrDefault(x => x.Id == origMember.Id);
if (liveMember != null)
{
liveMember.Status = LiveConsultationMemberStatus.Accepted;
liveMember.Mute = origMember.Mute;
liveMember.VideoOpend = origMember.VideoOpend;
liveMember.IsControllingParameter = origMember.IsControllingParameter;
}
else
{
closeMemberCodes.Add(origMember.Id);
}
}
PushCloseDueToChangeMessage(closeMemberCodes);
PushChangeRoomMessage(userCode, current);
Close(false);
}
private void StartCheckConnectionTimeout(int timeout)
{
Task.Run(async () =>
{
Status = LiveConsultationRoomStatus.Initiating;
await Task.Delay(timeout * 1000);
if (Status != LiveConsultationRoomStatus.Connected)
{
Status = LiveConsultationRoomStatus.ConnectionTimeout;
}
});
}
public LiveConsultationMember InitLiveMemberByCode(string userCode)
{
var user = CacheMaintenance.Instance.Get().Get(userCode);
var userName = !string.IsNullOrWhiteSpace(user.FullName) ? user.FullName : user.UserName;
var liveMember = new LiveConsultationMember
{
Id = userCode,
MemberType = LiveMemberEnum.User,
Name = userName,
HeadImageToken = user.HeadImageToken,
IsInitiator = false,
Status = LiveConsultationMemberStatus.Default,
//LiveData = liveData,
};
var userToken = CacheMaintenance.Instance.Get().Where(t => t.ClientId == userCode)?.OrderByDescending(x => x.IsOnline)?.FirstOrDefault();
if (userToken != null)
{
var loginSource = (LoginSource)userToken.LoginSource;
liveMember.LoginServerUrl = userToken.LoginServer;
liveMember.LoginSource = (LoginSource)userToken.LoginSource;
liveMember.IsOnline = userToken.IsOnline;
liveMember.IsBusy = false;
}
return liveMember;
}
private void RefreshMemberInfosByToken(string liveMemberId = "")
{
var tokenManager = CacheMaintenance.Instance.Get();
foreach (var liveMember in Members)
{
var id = liveMember.Id;
if (!string.IsNullOrWhiteSpace(liveMemberId) && id != liveMemberId)
{
continue;
}
var userToken = tokenManager.Where(t => t.ClientId == id)?.OrderByDescending(x => x.IsOnline)?.FirstOrDefault();
if (userToken != null)
{
var loginSource = (LoginSource)userToken.LoginSource;
liveMember.LoginServerUrl = userToken.LoginServer;
liveMember.LoginSource = (LoginSource)userToken.LoginSource;
liveMember.IsOnline = userToken.IsOnline;
}
var agenerateRoomUrlResult = OnRtcGenerateRoomUrl.Invoke(RoomNo, id);
liveMember.LiveData = new LiveData
{
RtmpPullUrl = agenerateRoomUrlResult.RtmpUrl,
HlsPullUrl = agenerateRoomUrlResult.HlsUrl,
HttpPullUrl = agenerateRoomUrlResult.FlvUrl,
};
}
}
private void WriteDebugLogs(string actionName, LiveConsultationMember liveMember = null, string log = "")
{
var logs = new StringBuilder();
logs.AppendLine($"LiveConsultationRoom action:{actionName}, patientName:{PatientName}, roomId:{RoomId}, room status:{Status.ToString()}");
if (liveMember != null)
{
logs.AppendLine($"user:{liveMember.Name}, status:{liveMember.Status.ToString()}");
}
else
{
logs.AppendLine($"user:not existed");
}
logs.AppendLine($"log:{log}");
Logger.WriteLineInfo($"{logs.ToString()}");
}
///
/// 清除白板数据
///
///
private void RemoveInteractiveBoardDatasByUserCode(string userCode)
{
InteractiveBoardDatas = InteractiveBoardDatas.Where(x => x.UserCode != userCode)?.ToList() ?? new List();
}
}
public class LiveConsultationRoomDTO
{
public LiveConsultationRoomDTO(string roomId)
{
RoomId = roomId;
}
///
/// The consultation unique id
///
///
public string RoomId { get; set; }
///
/// The diagnosis room No
///
///
public int RoomNo { get; set; }
public string MsgQueueId { get; set; }
public IList Members { get; set; } = new List();
public LiveConsultationMember Initiator
{
get
{
return Members.FirstOrDefault(x => x.IsInitiator);
}
}
public IEnumerable UserInfos
{
get
{
return Members.Where(x => x.MemberType == LiveMemberEnum.User);
}
}
public IEnumerable DeviceInfos
{
get
{
return Members.Where(x => x.MemberType == LiveMemberEnum.Device);
}
}
public IEnumerable MainUserInfos
{
get
{
return Members.Where(x => x.IsInitiator || x.Id == ApplyUserCode || x.Id == ExpertUserCode);
}
}
///
/// The diagnosis room status
///
///
public LiveConsultationRoomStatus Status { get; set; }
///
/// 病人名称
///
public string PatientName { get; set; }
///
/// 会诊时间
///
public DateTime ConsultationTime { get; set; }
///
/// 会诊状态
///
public TransactionStatusEnum ConsultationStatus { get; set; }
///
/// 申请机构编码
///
public string ApplyOrganizationCode { get; set; }
///
/// 申请医师编码
///
public string ApplyUserCode { get; set; }
///
/// 会诊机构编码
///
public string ExpertOrganizationCode { get; set; }
///
/// 会诊专家编码
///
public string ExpertUserCode { get; set; }
///
/// 是否急诊标识
///
///
public bool IsEmergency { get; set; }
///
/// 急诊已接通
///
///
public bool EmergencyAccepted { get; set; }
///
/// 白板数据集合
///
///
///
public IList InteractiveBoardDatas { get; set; } = new List();
}
}