DeviceService.cs 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using WingInterfaceLibrary.DTO.Device;
  6. using WingInterfaceLibrary.Interface;
  7. using WingInterfaceLibrary.Request.Device;
  8. using WingInterfaceLibrary.DTO.Dictionary;
  9. using WingServerCommon.Log;
  10. using WingServerCommon.Service;
  11. using WingInterfaceLibrary.Interface.DBInterface;
  12. using WingInterfaceLibrary.DB.Request;
  13. using WingServerCommon.Mapper;
  14. using WingInterfaceLibrary.Request;
  15. using WingInterfaceLibrary.Request.Authentication;
  16. using WingInterfaceLibrary.DTO.User;
  17. using WingInterfaceLibrary.DTO.Management;
  18. using WingServerCommon.Config;
  19. using WingDeviceService.Common;
  20. using WingInterfaceLibrary.Request.User;
  21. using WingInterfaceLibrary.Enum;
  22. using WingInterfaceLibrary.DTO.Organization;
  23. using WingInterfaceLibrary.DTO.DiagnosisModule;
  24. using WingServerCommon.Config.Parameters;
  25. using WingServerCommon.Interfaces.Cache;
  26. using WingInterfaceLibrary.LiveConsultation;
  27. using WingInterfaceLibrary.Result.Languge;
  28. using WingInterfaceLibrary.Internal.Interface;
  29. using WingInterfaceLibrary.Notifications;
  30. using WingInterfaceLibrary.Internal.Request;
  31. using WingInterfaceLibrary.Rtc;
  32. using WingInterfaceLibrary.Enum.CommentEnum;
  33. using WingInterfaceLibrary.DTO.RTC;
  34. using Newtonsoft.Json;
  35. using WingInterfaceLibrary.Notifications.Live;
  36. using WingInterfaceLibrary.Enum.NotificationEnum;
  37. namespace WingDeviceService.Service
  38. {
  39. /// <summary>
  40. /// 设备管理服务
  41. /// </summary>
  42. public partial class DeviceService : JsonRpcService, IDeviceService
  43. {
  44. private IUserDBService _userServiceProxy;
  45. private IDeviceInfoDBService _deviceInfoDBServiceProxy;
  46. private IAuthenticationService _authenticationService;
  47. private IOrganizationDBService _organizationDBService;
  48. private INotificationService _notificationService;
  49. private IRecordsInfoDBService _recordsInfoDBService;
  50. private IPatientInfoDBService _patientInfoDBService;
  51. private IDiagnosisModuleDBService _diagnosisModuleService;
  52. private IRemedicalService _remedicalService;
  53. private IWingRtcService _rtcService;
  54. private int _heartRateSeconds;
  55. private DeviceHeartRateManager _deviceHeartRateManager;
  56. private string _webSocketUrl = string.Empty;
  57. private int _liveConsultationRateSeconds = 0;
  58. private bool _isRTCSelf = false;
  59. private int _sdkAppId = 0;
  60. private int _reportStateIntervalSeconds = 0;
  61. private int _reportStateTimeout = 0;
  62. /// <summary>
  63. /// Init service
  64. /// </summary>
  65. public override void Load(JsonRpcClientPool jsonRpcClientPool)
  66. {
  67. base.Load(jsonRpcClientPool);
  68. _userServiceProxy = GetProxy<IUserDBService>();
  69. _authenticationService = GetProxy<IAuthenticationService>();
  70. _deviceInfoDBServiceProxy = GetProxy<IDeviceInfoDBService>();
  71. _organizationDBService = GetProxy<IOrganizationDBService>();
  72. _notificationService = GetProxy<INotificationService>();
  73. _recordsInfoDBService = GetProxy<IRecordsInfoDBService>();
  74. _patientInfoDBService = GetProxy<IPatientInfoDBService>();
  75. _diagnosisModuleService = GetProxy<IDiagnosisModuleDBService>();
  76. _remedicalService = GetProxy<IRemedicalService>();
  77. _rtcService = GetProxy<IWingRtcService>();
  78. _heartRateSeconds = ConfigurationManager.GetParammeter<IntParameter>("Device", "HeartRateSeconds").Value;
  79. _deviceHeartRateManager = new DeviceHeartRateManager(SetOnlineState);
  80. _webSocketUrl = ConfigurationManager.GetParammeter<StringParameter>("Notification", "WebSocketUrl").Value;
  81. _liveConsultationRateSeconds = ConfigurationManager.GetParammeter<IntParameter>("Live", "HeartRateSeconds").Value;
  82. _isRTCSelf = ConfigurationManager.GetParammeter<BoolParameter>("Rtc", "IsSelf").Value;
  83. var sdkAppIdString = ConfigurationManager.GetParammeter<StringParameter>("Rtc", "RTCAppId").Value;
  84. if (int.TryParse(sdkAppIdString, out int sdkAppId))
  85. {
  86. _sdkAppId = sdkAppId;
  87. }
  88. var _reportStateIntervalSeconds = ConfigurationManager.GetParammeter<IntParameter>("Live", "ReportStateIntervalSeconds").Value;
  89. var _reportStateTimeout = ConfigurationManager.GetParammeter<IntParameter>("Live", "ReportStateTimeout").Value;
  90. }
  91. /// <summary>
  92. /// 设备心跳
  93. /// </summary>
  94. /// <param name="request"></param>
  95. /// <returns></returns>
  96. public async Task<bool> HeartRateAsync(TokenRequest request)
  97. {
  98. _deviceHeartRateManager.AddOrUpdate(request.Token);
  99. var result = SetOnlineState(request.Token, true);
  100. return result;
  101. }
  102. private bool SetOnlineState(string token, bool isOnline)
  103. {
  104. return _authenticationService.SetOnlineStateAsync(new SetOnlineStateRequest { Token = token, IsOnline = isOnline }).Result;
  105. }
  106. /// <summary>
  107. /// 添加分享设备关联用户请求
  108. /// </summary>
  109. /// <param name="request"></param>
  110. /// <returns></returns>
  111. public async Task<bool> CreateShareDeviceToUserAsync(CreateShareDeviceToUserRequest request)
  112. {
  113. var userCodes = request.UserCodes;
  114. var deviceCode = request.DeviceCode;
  115. //检查设备编码不为空
  116. if (string.IsNullOrWhiteSpace(request.DeviceCode))
  117. {
  118. ThrowCustomerException(CustomerRpcCode.DeviceCodeIsEmpty, "Required parameter:DeviceCode cannot be empty");
  119. }
  120. if (userCodes == null || userCodes.Count <= 0)
  121. {
  122. ThrowCustomerException(CustomerRpcCode.UserCodeEmptyError, "Required parameter:UserCodes cannot be empty");
  123. }
  124. //查询设备对象
  125. var deviceDb = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(deviceCode);
  126. if (deviceDb == null)
  127. {
  128. ThrowCustomerException(CustomerRpcCode.NoExistDevice, "Device does not exist");
  129. }
  130. foreach (var userCode in userCodes)
  131. {
  132. var existUser = await _userServiceProxy.FindUserByCodeAsync(userCode);
  133. if (existUser == null)
  134. {
  135. ThrowCustomerException(CustomerRpcCode.UserNotExistError, "User does not exist");
  136. }
  137. }
  138. await _userServiceProxy.BingDevicesToUsersAsync(new BingDevicesToUsersRequest
  139. {
  140. DeviceCodes = new List<string> { deviceCode },
  141. UserCodes = userCodes.ToList()
  142. });
  143. return true;
  144. }
  145. /// <summary>
  146. /// 根据设备code获取设备信息
  147. /// </summary>
  148. /// <param name="request">设备code请求实体</param>
  149. /// <returns>返回查询到的设备对象信息</returns>
  150. public async Task<DeviceExtendInfoDTO> GetDeviceInfoAsync(GetDeviceRequest request)
  151. {
  152. //验证
  153. if (string.IsNullOrWhiteSpace(request.DeviceCode))
  154. {
  155. ThrowCustomerException(CustomerRpcCode.DeviceCodeEmpty, "DeviceCode empty error");
  156. }
  157. var deviceDb = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(request.DeviceCode);
  158. if (deviceDb == null || deviceDb.DeviceCode != request.DeviceCode)
  159. {
  160. ThrowCustomerException(CustomerRpcCode.NoExistDevice, "Device does not exist");
  161. }
  162. //根据机构编号查询机构名称
  163. var organizationName = "";
  164. if (!string.IsNullOrEmpty(deviceDb.OrganizationCode))
  165. {
  166. var organization = await _organizationDBService.GetOrganizationDetailAsync(new GetOrganizationDBRequest { OrganizationCode = deviceDb.OrganizationCode });
  167. organizationName = organization?.OrganizationName ?? string.Empty;
  168. }
  169. //根据机构编号查询科室名称
  170. var departmentName = "";
  171. if (!string.IsNullOrEmpty(deviceDb.DepartmentCode))
  172. {
  173. var department = await _organizationDBService.GetOrganizationDetailAsync(new GetOrganizationDBRequest { OrganizationCode = deviceDb.DepartmentCode });
  174. departmentName = department?.OrganizationName ?? string.Empty;
  175. }
  176. //是否在线 todo
  177. var deviceTypeModel = await _deviceInfoDBServiceProxy.FindDictionaryByCodeAsync(deviceDb.DeviceType);
  178. var result = new DeviceExtendInfoDTO()
  179. {
  180. DepartmentName = departmentName,
  181. OrganizationName = organizationName,
  182. IsOnline = await GetDeviceOnlineState(deviceDb.DeviceCode),
  183. DeviceCode = deviceDb.DeviceCode,
  184. SerialNumber = deviceDb.SerialNumber,
  185. Name = deviceDb.Name,
  186. Description = deviceDb.Description,
  187. DeviceModel = deviceDb.DeviceModel,
  188. DeviceType = deviceDb.DeviceType,
  189. HeadPicUrl = deviceDb.HeadPicUrl,
  190. DeviceSoftwareVersion = deviceDb.DeviceSoftwareVersion,
  191. SDKSoftwareVersion = deviceDb.SDKSoftwareVersion,
  192. OrganizationCode = deviceDb.OrganizationCode,
  193. DepartmentCode = deviceDb.DepartmentCode,
  194. ShortCode = deviceDb.ShortCode,
  195. LanguageConfigs = deviceTypeModel.LanguageConfigs
  196. };
  197. return result;
  198. }
  199. /// <summary>
  200. /// 根据设备动态唯一码获取设备信息
  201. /// </summary>
  202. /// <param name="request"></param>
  203. /// <returns></returns>
  204. public async Task<DeviceExtendInfoDTO> GetDeviceByShortCodeAsync(GetDeviceByShortCodeRequest request)
  205. {
  206. //验证
  207. if (string.IsNullOrWhiteSpace(request.ShortCode))
  208. {
  209. ThrowCustomerException(CustomerRpcCode.ShortCodeEmpty, "ShortCode empty error");
  210. }
  211. var deviceDb = await _deviceInfoDBServiceProxy.FindDeviceInfoByShortCodeAsync(request.ShortCode);
  212. if (deviceDb == null || deviceDb.ShortCode != request.ShortCode)
  213. {
  214. ThrowCustomerException(CustomerRpcCode.NoExistDevice, "Device does not exist");
  215. }
  216. return await MapToExtendDTO(deviceDb);
  217. }
  218. public async Task<PageCollection<DeviceInfoDTO>> GetDeviceInfoPageAsync(PageFilterRequest request)
  219. {
  220. throw new System.NotImplementedException();
  221. }
  222. public async Task<bool> DeleteShareDeviceToUserAsync(DeleteShareDeviceToUserRequest request)
  223. {
  224. var userCodes = request.UserCodes;
  225. var deviceCode = request.DeviceCode;
  226. //检查设备编码不为空
  227. if (string.IsNullOrWhiteSpace(request.DeviceCode))
  228. {
  229. ThrowCustomerException(CustomerRpcCode.DeviceCodeIsEmpty, "Required parameter:DeviceCode cannot be empty");
  230. }
  231. //用户编码集合检查
  232. if (userCodes == null || userCodes.Count <= 0)
  233. {
  234. ThrowCustomerException(CustomerRpcCode.UserCodeEmptyError, "Required parameter:UserCodes cannot be empty");
  235. }
  236. //查询设备对象
  237. var deviceDb = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(deviceCode);
  238. if (deviceDb == null)
  239. {
  240. ThrowCustomerException(CustomerRpcCode.NoExistDevice, "Device does not exist");
  241. }
  242. var updateUsers = new List<TableDataItem<UserPasswordDTO>>();
  243. foreach (var userCode in userCodes)
  244. {
  245. var user = await _userServiceProxy.FindUserByCodeAsync(userCode);
  246. if (user != null)
  247. {
  248. if (user.BindDevices.Contains(deviceCode))
  249. {
  250. user.BindDevices.Remove(deviceCode);
  251. updateUsers.Add(new TableDataItem<UserPasswordDTO>()
  252. {
  253. Data = user.MappingTo<UserPasswordDTO>(),
  254. });
  255. }
  256. }
  257. }
  258. if (updateUsers.Count > 0)
  259. {
  260. var updateUsersDBRequest = new UpdateUsersDBRequest() { Users = updateUsers };
  261. await _userServiceProxy.UpdateUsersAsync(updateUsersDBRequest);
  262. }
  263. return true;
  264. }
  265. /// <summary>
  266. /// 机构设备移除-根据机构code和设备code解除其绑定关系
  267. /// </summary>
  268. /// <param name="request">移除设备请求实体</param>
  269. /// <returns>移除是否成功:true-成功;false-失败</returns>
  270. public async Task<bool> RemoveDeviceRelevancyAsync(RemoveDeviceRelevancyRequest request)
  271. {
  272. //验证
  273. if (string.IsNullOrWhiteSpace(request.DeviceCode) || string.IsNullOrWhiteSpace(request.OrganizationCode))
  274. {
  275. ThrowCustomerException(CustomerRpcCode.DeviceCodeOrOrganizationCodeEmpty, "DeviceCode Or OrganizationCode empty error");
  276. }
  277. var deviceDb = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(request.DeviceCode);
  278. if (deviceDb == null || deviceDb.OrganizationCode != request.OrganizationCode || deviceDb.DepartmentCode != request.DepartmentCode)
  279. {
  280. ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "DeviceInfo not exist error");
  281. }
  282. //根据设备code和机构code查询相关数据,查到则删除关联
  283. if (!string.IsNullOrEmpty(deviceDb.DepartmentCode))
  284. {
  285. deviceDb.DepartmentCode = "";
  286. deviceDb.OrganizationCode = "";
  287. }
  288. else
  289. {
  290. deviceDb.OrganizationCode = "";
  291. }
  292. bool removeDeviceResult = await _deviceInfoDBServiceProxy.UpdateDeviceInfoByCodeAsync(deviceDb.DeviceCode, deviceDb, string.Empty, true);
  293. return removeDeviceResult;
  294. }
  295. private async Task<string> GetClientIdByTokenAsync(string token)
  296. {
  297. var request = new TokenRequest() { Token = token };
  298. var result = await _authenticationService.GetTokenAsync(request);
  299. return result.ClientId; //return User code
  300. }
  301. /// <summary>
  302. /// 查询个人名下所有设备列表接口
  303. /// </summary>
  304. /// <param name="request">查询个人名下所有设备列表请求实体</param>
  305. /// <returns>返回设备信息列表</returns>
  306. public async Task<PageCollection<DeviceExtendInfoDTO>> GetPersonDeviceListAsync(GetPersonDeviceRequest request)
  307. {
  308. //验证
  309. var userCode = await GetClientIdByTokenAsync(request.Token);
  310. //查询用户是否存在
  311. var userInfoDO = await _userServiceProxy.FindUserByCodeAsync(userCode);
  312. if (userInfoDO == null)
  313. {
  314. ThrowCustomerException(CustomerRpcCode.UserNotExistError, "User does not exist");
  315. }
  316. //查询用户的医院是否存在
  317. if (string.IsNullOrWhiteSpace(userInfoDO.OrganizationCode))
  318. {
  319. ThrowCustomerException(CustomerRpcCode.OrganizationNotExist, "Org does not exist");
  320. }
  321. var deviceInfoDOList = new List<DeviceInfoDTO>();
  322. if (!userInfoDO.IsDirector)
  323. {
  324. //普通用户,查询用户绑定的设备
  325. if (userInfoDO.BindDevices != null && userInfoDO.BindDevices.Any())
  326. {
  327. deviceInfoDOList = await _deviceInfoDBServiceProxy.FindDeviceInfoListByCodeListAsync(userInfoDO.BindDevices);
  328. }
  329. }
  330. else
  331. {
  332. //机构负责人
  333. deviceInfoDOList = await _deviceInfoDBServiceProxy.FindDeviceInfoListByOrganizationCodeAsync(userInfoDO.RootOrganizationCode);
  334. }
  335. if (!deviceInfoDOList.Any())
  336. {
  337. return new PageCollection<DeviceExtendInfoDTO>() { CurrentPage = request.PageIndex, PageSize = request.PageSize, DataCount = 0, PageData = new List<DeviceExtendInfoDTO>() };
  338. }
  339. var deviceList = await MapToExtendDTO(deviceInfoDOList);
  340. //条件筛选
  341. if (!string.IsNullOrWhiteSpace(request.DeviceType))
  342. {
  343. deviceList = deviceList.Where(d => d.DeviceType == request.DeviceType)?.ToList() ?? new List<DeviceExtendInfoDTO>();
  344. }
  345. if (!string.IsNullOrWhiteSpace(request.DeviceModel))
  346. {
  347. deviceList = deviceList.Where(d => d.DeviceModel == request.DeviceModel)?.ToList() ?? new List<DeviceExtendInfoDTO>();
  348. }
  349. if (!string.IsNullOrWhiteSpace(request.KeyWord))
  350. {
  351. var keyword = request.KeyWord.Trim().ToLower();
  352. deviceList = deviceList.Where(d => d.Name.ToLower().Contains(keyword) || d.ShortCode.ToLower().Contains(keyword))?.ToList() ?? new List<DeviceExtendInfoDTO>();
  353. }
  354. if (request.IsOnline != null)
  355. {
  356. deviceList = deviceList.Where(d => d.IsOnline == request.IsOnline)?.ToList() ?? new List<DeviceExtendInfoDTO>();
  357. }
  358. var pagedResult = new PageCollection<DeviceExtendInfoDTO>
  359. {
  360. CurrentPage = request.PageIndex,
  361. PageSize = request.PageSize,
  362. DataCount = deviceList.Count,
  363. PageData = deviceList.Skip(request.PageSize * (request.PageIndex - 1)).Take(request.PageSize)?.ToList() ?? new List<DeviceExtendInfoDTO>()
  364. };
  365. return pagedResult;
  366. }
  367. /// <summary>
  368. /// 绑定设备
  369. /// </summary>
  370. /// <param name="request"></param>
  371. /// <returns></returns>
  372. public async Task<bool> BindDeviceAsync(BindDeviceRequest request)
  373. {
  374. //验证
  375. var userCode = await GetClientIdByTokenAsync(request.Token);
  376. //查询用户是否存在
  377. var userInfoDO = await _userServiceProxy.FindUserByCodeAsync(userCode);
  378. if (userInfoDO == null)
  379. {
  380. ThrowCustomerException(CustomerRpcCode.UserNotExistError, "User does not exist");
  381. }
  382. var deviceDb = await _deviceInfoDBServiceProxy.FindDeviceInfoByShortCodeAsync(request.ShortCode);
  383. if (deviceDb == null)
  384. {
  385. ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "Not find device");
  386. }
  387. if (userInfoDO.BindDevices != null && userInfoDO.BindDevices.Contains(deviceDb.DeviceCode))
  388. {
  389. ThrowCustomerException(CustomerRpcCode.HasAddedDevice, "The device has been Added");
  390. }
  391. try
  392. {
  393. var isInvented = (string.IsNullOrWhiteSpace(deviceDb.OrganizationCode) || deviceDb.OrganizationCode == $"invented_{deviceDb.ShortCode}") ? true : false;
  394. deviceDb.Name = request.Name;
  395. deviceDb.SerialNumber = request.SerialNumber;
  396. deviceDb.Description = request.Description;
  397. if (!string.IsNullOrEmpty(request.HeadPicUrl))
  398. {
  399. deviceDb.HeadPicUrl = request.HeadPicUrl.ToUrlToken();
  400. }
  401. deviceDb.DepartmentCode = request.DepartmentCode;
  402. deviceDb.IsAutoShared = request.IsAutoShared;
  403. deviceDb.OrganizationCode = request.OrganizationCode;
  404. await _deviceInfoDBServiceProxy.UpdateDeviceInfoByCodeAsync(deviceDb.DeviceCode, deviceDb, string.Empty);
  405. if (isInvented && !string.IsNullOrWhiteSpace(request.OrganizationCode)) //虚拟机构改为正常机构
  406. {
  407. var newOrgCode = string.IsNullOrWhiteSpace(request.DepartmentCode) ? request.OrganizationCode : request.DepartmentCode;
  408. //迁移数据超声机上传检查记录
  409. await _recordsInfoDBService.UpdateRecordsWithOrgCodeAsync(new List<string>() { deviceDb.DeviceCode }, newOrgCode);
  410. //迁移数据超声机上传病人
  411. await _patientInfoDBService.UpdatePatientWithOrgCodeAsync(new List<string>() { deviceDb.DeviceCode }, newOrgCode);
  412. }
  413. if (deviceDb.IsAutoShared)
  414. {
  415. var users = new List<UserDTO>();
  416. if (!string.IsNullOrEmpty(deviceDb.DepartmentCode))
  417. {
  418. users = await _userServiceProxy.FindUserListByOrganizationCodesAsync(new List<string> { deviceDb.DepartmentCode });
  419. }
  420. else
  421. {
  422. users = await _userServiceProxy.GetUserListAsync(new GetUserListDBRequest { OrganizationQueryType = OrganizationQueryTypeEnum.All, OrganizationCode = deviceDb.OrganizationCode });
  423. }
  424. var userCodes = users.Select(f => f.UserCode).ToList();
  425. await _userServiceProxy.BingDevicesToUsersAsync(new BingDevicesToUsersRequest
  426. {
  427. DeviceCodes = new List<string> { deviceDb.DeviceCode.ToString() },
  428. UserCodes = userCodes.Select(f => f.ToString()).ToList()
  429. });
  430. }
  431. return true;
  432. }
  433. catch (Exception ex)
  434. {
  435. Logger.WriteLineError($"BindDeviceAsync error {ex}");
  436. }
  437. return false;
  438. }
  439. /// <summary>
  440. /// 修改设备
  441. /// </summary>
  442. /// <param name="request"></param>
  443. /// <returns></returns>
  444. public async Task<bool> ModifyDeviceAsync(ModifyDeviceRequest request)
  445. {
  446. var deviceDb = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(request.DeviceCode);
  447. if (deviceDb == null)
  448. {
  449. ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "Not find device");
  450. }
  451. if (string.IsNullOrWhiteSpace(request.Name))
  452. {
  453. ThrowCustomerException(CustomerRpcCode.DeviceNameEmpty, "Device name cannot be empty");
  454. }
  455. deviceDb.Name = request.Name;
  456. if (!string.IsNullOrWhiteSpace(request.HeadPicUrl))
  457. {
  458. deviceDb.HeadPicUrl = request.HeadPicUrl.ToUrlToken();
  459. }
  460. else
  461. {
  462. deviceDb.HeadPicUrl = string.Empty;
  463. }
  464. deviceDb.DepartmentCode = request.DepartmentCode;
  465. //修改自动分享
  466. deviceDb.IsAutoShared = request.IsAutoShared;
  467. if (deviceDb.IsAutoShared)
  468. {
  469. var users = new List<UserDTO>();
  470. if (!string.IsNullOrEmpty(deviceDb.DepartmentCode))
  471. {
  472. users = await _userServiceProxy.FindUserListByOrganizationCodesAsync(new List<string> { deviceDb.DepartmentCode });
  473. }
  474. else
  475. {
  476. users = await _userServiceProxy.GetUserListAsync(new GetUserListDBRequest { OrganizationQueryType = OrganizationQueryTypeEnum.All, OrganizationCode = deviceDb.OrganizationCode });
  477. }
  478. var userCodes = users.Select(f => f.UserCode).ToList();
  479. //先解绑,再绑定,避免绑定重复设备code
  480. var updateUsers = new List<TableDataItem<UserPasswordDTO>>();
  481. foreach (var user in users)
  482. {
  483. var userPasswordDTO = user.MappingTo<UserPasswordDTO>();
  484. user.BindDevices?.Remove(deviceDb.DeviceCode);
  485. await _userServiceProxy.UpdateUserAsync(userPasswordDTO.UserCode, userPasswordDTO, string.Empty);
  486. }
  487. await _userServiceProxy.BingDevicesToUsersAsync(new BingDevicesToUsersRequest
  488. {
  489. DeviceCodes = new List<string> { deviceDb.DeviceCode.ToString() },
  490. UserCodes = userCodes.Select(f => f.ToString()).ToList()
  491. });
  492. }
  493. return await _deviceInfoDBServiceProxy.UpdateDeviceInfoByCodeAsync(deviceDb.DeviceCode, deviceDb, string.Empty, true);
  494. }
  495. /// <summary>
  496. /// 创建字典
  497. /// </summary>
  498. /// <param name="request"></param>
  499. /// <returns></returns>
  500. public async Task<string> CreateDictionaryItemAsync(CreateDictionaryItemRequest request)
  501. {
  502. return await _deviceInfoDBServiceProxy.CreateDictionaryItemAsync(new CreateDictionaryItemDBRequest
  503. {
  504. Data = new DictionaryDTO { DictionaryType = request.DictionaryType, Value = request.DictionaryItemValue, ParentCode = request.ParentCode },
  505. ExtensionData = string.Empty
  506. });
  507. }
  508. /// <summary>
  509. /// 查找设备型号所有字典项
  510. /// </summary>
  511. /// <param name="request"></param>
  512. /// <returns></returns>
  513. public async Task<List<DictionaryDTO>> FindDeviceModelItemsAsync(FindDeviceModelItemsRequest request)
  514. {
  515. var dictionaryDOList = await _deviceInfoDBServiceProxy.FindDictionaryItemsAsync(new FindDictionaryItemsDBRequest
  516. {
  517. DictionaryType = (int)request.DictionaryType,
  518. ParentCode = request.DeviceTypeCode
  519. });
  520. return dictionaryDOList;
  521. }
  522. /// <summary>
  523. /// 查找设备类型所有字典项
  524. /// </summary>
  525. /// <param name="request"></param>
  526. /// <returns></returns>
  527. public async Task<List<DictionaryDTO>> FindDeviceTypeItemsAsync(FindDeviceTypeItemsRequest request)
  528. {
  529. var dictionaryDOList = await _deviceInfoDBServiceProxy.FindDictionaryItemsAsync(new FindDictionaryItemsDBRequest
  530. {
  531. DictionaryType = (int)request.DictionaryType
  532. });
  533. return dictionaryDOList;
  534. }
  535. /// <summary>
  536. /// 根据组织编码查询所属全部设备信息
  537. /// </summary>
  538. /// <param name="request"></param>
  539. /// <returns></returns>
  540. public async Task<List<DeviceExtendInfoDTO>> FindDevicesByOrganizationCodeAsync(FindDevicesByOrganizationCodeRequest request)
  541. {
  542. var result = new List<DeviceExtendInfoDTO>();
  543. var deviceInfoDOList = await _deviceInfoDBServiceProxy.FindDeviceInfoListByOrganizationCodeAsync(request.OrganizationCode);
  544. if (deviceInfoDOList?.Count > 0)
  545. {
  546. //根据机构编号查询机构名称
  547. var organizationCode = deviceInfoDOList.FindAll(c => !string.IsNullOrEmpty(c.OrganizationCode)).Select(c => c.OrganizationCode).FirstOrDefault() ?? string.Empty;
  548. var organization = await _organizationDBService.GetOrganizationDetailAsync(new GetOrganizationDBRequest { OrganizationCode = organizationCode });
  549. var organizationName = organization?.OrganizationName ?? string.Empty;
  550. //根据机构编号查询科室名称
  551. var organizationFilter = new Dictionary<string, string>();
  552. organizationFilter.Add("RootCode", organizationCode);
  553. var organizations = await _organizationDBService.GetOrganizationPageAsync((new PageFilterRequest { CurrentPage = 1, PageSize = 999999, Filter = organizationFilter, IsFuzzy = false }));
  554. var deviceCodes = deviceInfoDOList.Select(x => x.DeviceCode).ToList();
  555. var deviceTokens = await _authenticationService.GetTokenWithClientIdsAsync(new GetTokenWithClientIdsRequest { ClientIds = deviceCodes });
  556. var deviceTypeList = await _deviceInfoDBServiceProxy.FindDictionaryItemsAsync(new FindDictionaryItemsDBRequest { DictionaryType = (int)DictionaryTypeEnum.DeviceType });
  557. foreach (var c in deviceInfoDOList)
  558. {
  559. var deviceTypeModel = deviceTypeList.FirstOrDefault(t => t.DictionaryCode == c.DeviceType);
  560. result.Add(new DeviceExtendInfoDTO
  561. {
  562. DepartmentName = organizations.PageData.FirstOrDefault(o => o.OrganizationCode == c.DepartmentCode)?.OrganizationName,
  563. OrganizationName = organizationName,
  564. IsOnline = deviceTokens.FirstOrDefault(x => x.ClientId == c.DeviceCode)?.IsOnline ?? false,
  565. DeviceCode = c.DeviceCode,
  566. SerialNumber = c.SerialNumber,
  567. Name = c.Name,
  568. Description = c.Description,
  569. DeviceModel = c.DeviceModel,
  570. DeviceType = c.DeviceType,
  571. HeadPicUrl = c.HeadPicUrl,
  572. DeviceSoftwareVersion = c.DeviceSoftwareVersion,
  573. SDKSoftwareVersion = c.SDKSoftwareVersion,
  574. OrganizationCode = c.OrganizationCode,
  575. DepartmentCode = c.DepartmentCode,
  576. ShortCode = c.ShortCode,
  577. LanguageConfigs = deviceTypeModel?.LanguageConfigs
  578. });
  579. }
  580. }
  581. return result;
  582. }
  583. public Task<DeviceInfoDTO> CreateDeviceInfoAsync(CreateDeviceRequest request)
  584. {
  585. throw new NotImplementedException();
  586. }
  587. public async Task<List<SelectItemDTO>> GetPersonDeviceDropdownListAsync(TokenRequest request)
  588. {
  589. //验证
  590. var userCode = await GetClientIdByTokenAsync(request.Token);
  591. //查询用户是否存在
  592. var userInfoDO = await _userServiceProxy.FindUserByCodeAsync(userCode);
  593. if (userInfoDO == null)
  594. {
  595. ThrowCustomerException(CustomerRpcCode.UserNotExistError, "User does not exist");
  596. }
  597. var result = new List<SelectItemDTO>();
  598. //查询用户的医院是否存在
  599. if (string.IsNullOrEmpty(userInfoDO.OrganizationCode))
  600. {
  601. ThrowCustomerException(CustomerRpcCode.OrganizationNotExist, "Org does not exist");
  602. }
  603. var deviceInfoDOList = new List<DeviceInfoDTO>();
  604. if (userInfoDO.IsDirector)
  605. {
  606. deviceInfoDOList = await _deviceInfoDBServiceProxy.FindDeviceInfoListByOrganizationCodeAsync(userInfoDO.RootOrganizationCode);
  607. }
  608. else if (!userInfoDO.RoleCodes.Contains("Role_ExpertAssistant"))
  609. {
  610. //查询用户绑定的设备
  611. if (userInfoDO.BindDevices == null || userInfoDO.BindDevices.Count <= 0)
  612. {
  613. return result;
  614. }
  615. //根据用户名下的设备id查询所有的设备信息
  616. deviceInfoDOList = await _deviceInfoDBServiceProxy.FindDeviceInfoListByCodeListAsync(userInfoDO.BindDevices);
  617. }
  618. else
  619. {
  620. var experts = await _userServiceProxy.GetBindExpertsAsync(userCode);
  621. if (experts.Any())
  622. {
  623. var bindDeviceCodes = experts.SelectMany(x => x.BindDevices ?? new List<string>()).Distinct().ToList();
  624. if (bindDeviceCodes.Any())
  625. {
  626. deviceInfoDOList = await _deviceInfoDBServiceProxy.FindDeviceInfoListByCodeListAsync(bindDeviceCodes);
  627. }
  628. }
  629. else
  630. {
  631. deviceInfoDOList = await _deviceInfoDBServiceProxy.FindDeviceInfoListByOrganizationCodeAsync(userInfoDO.RootOrganizationCode);
  632. }
  633. }
  634. if (deviceInfoDOList?.Count > 0)
  635. {
  636. result = deviceInfoDOList.Select(c => new SelectItemDTO()
  637. {
  638. Key = c.DeviceCode,
  639. Value = c.Name
  640. }).ToList();
  641. }
  642. return result;
  643. }
  644. /// <summary>
  645. /// 设备端调用,查询获取服务器配置信息接口
  646. /// </summary>
  647. /// <param name="request">Token验证</param>
  648. /// <returns>服务器配置信息结果:key:字段,value:数据值,复杂类型可为json</returns>
  649. public async Task<DeviceServerSettingResult> QueryServerConfigAsync(TokenRequest request)
  650. {
  651. var deviceCode = await GetClientIdByTokenAsync(request.Token);
  652. var deviceInfo = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(deviceCode);
  653. if (deviceInfo == null || string.IsNullOrWhiteSpace(deviceInfo.DeviceCode))
  654. {
  655. ThrowCustomerException(CustomerRpcCode.NoExistDevice, "Device does not exist");
  656. }
  657. var org = new OrganizationDTO();
  658. if (!string.IsNullOrWhiteSpace(deviceInfo.OrganizationCode))
  659. {
  660. org = await _organizationDBService.GetOrganizationDetailAsync(new GetOrganizationDBRequest { OrganizationCode = deviceInfo.OrganizationCode });
  661. if (org == null)
  662. {
  663. org = new OrganizationDTO();
  664. }
  665. }
  666. var dictionary = new Dictionary<string, string>();
  667. //定义配置字段 并扩充字段,返回数据可持续更新接口文档,如果数据是复杂类型可以转成json
  668. //TODO 配置信息: 直播配置、存储配置、
  669. //存储上传图像或者视频是 是否本地上传缩略图
  670. var isUploadThumbnail = ConfigurationManager.RemedicalSettings.IsUploadThumbnail;
  671. dictionary.Add("IsUploadThumbnail", isUploadThumbnail.ToString());
  672. dictionary.Add("PatientType", org.PatientType.ToString());
  673. dictionary.Add("HeartRateSeconds", _heartRateSeconds.ToString());
  674. dictionary.Add("NotificationUrl", _webSocketUrl);
  675. dictionary.Add("MergedChannel", deviceInfo.MergedChannel.ToString());
  676. dictionary.Add("LiveConsultationRateSeconds", _liveConsultationRateSeconds.ToString());
  677. var result = new DeviceServerSettingResult()
  678. {
  679. ServerConfigList = dictionary,
  680. IsUploadThumbnail = isUploadThumbnail,
  681. PatientType = org.PatientType,
  682. HeartRateSeconds = _heartRateSeconds,
  683. NotificationUrl = _webSocketUrl,
  684. LiveConsultationRateSeconds = _liveConsultationRateSeconds,
  685. MergedChannel = deviceInfo.MergedChannel,
  686. MergedVideoOutputWidth = deviceInfo.MergedVideoOutputWidth,
  687. MergedVideoOutputHeight = deviceInfo.MergedVideoOutputHeight,
  688. IsSelfRtcService = _isRTCSelf
  689. };
  690. return result;
  691. }
  692. /// <summary>
  693. /// 添加或迁移设备到医院请求
  694. /// </summary>
  695. /// <param name="request"></param>
  696. /// <returns></returns>
  697. public async Task<bool> AddDeviceToOrgAsync(AddDeviceToOrgRequest request)
  698. {
  699. var shortCode = request.UniqueCode;
  700. #region Params Check
  701. var userCode = await GetClientIdByTokenAsync(request.Token);
  702. if (string.IsNullOrEmpty(shortCode))
  703. {
  704. ThrowCustomerException(CustomerRpcCode.UniqueCodeIsEmpty, "UniqueCode is empty");
  705. }
  706. var device = await _deviceInfoDBServiceProxy.FindDeviceInfoByShortCodeAsync(shortCode);
  707. if (device == null)
  708. {
  709. ThrowCustomerException(CustomerRpcCode.NoExistDevice, "Device does not exist");
  710. }
  711. var oldOrg = await _organizationDBService.GetOrganizationDetailAsync(new GetOrganizationDBRequest { OrganizationCode = device.OrganizationCode });
  712. if (oldOrg == null || string.IsNullOrWhiteSpace(oldOrg.OrganizationCode))
  713. {
  714. ThrowCustomerException(CustomerRpcCode.OrganizationNotExist, "Org does not exist");
  715. }
  716. //用户
  717. var userDTO = await _userServiceProxy.FindUserByCodeAsync(userCode);
  718. if (userDTO == null)
  719. {
  720. ThrowCustomerException(CustomerRpcCode.UserNotExistError, "User does not exist");
  721. }
  722. if (!userDTO.IsDirector)
  723. {
  724. ThrowCustomerException(CustomerRpcCode.NotOrgAdmin, "not org admin");
  725. }
  726. var org = await _organizationDBService.GetOrganizationDetailAsync(new GetOrganizationDBRequest { OrganizationCode = userDTO.OrganizationCode });
  727. if (org == null || string.IsNullOrWhiteSpace(org.OrganizationCode))
  728. {
  729. ThrowCustomerException(CustomerRpcCode.OrganizationNotExist, "Org does not exist");
  730. }
  731. #endregion
  732. try
  733. {
  734. var newOrgode = org.OrganizationCode;
  735. //设备更新医院
  736. if (!string.IsNullOrEmpty(device.DepartmentCode))
  737. {
  738. device.DepartmentCode = "";
  739. }
  740. if (!string.IsNullOrEmpty(device.Name))
  741. {
  742. device.Name = "";
  743. }
  744. device.HeadPicUrl = "";
  745. device.Description = "";
  746. device.IsAutoShared = false;
  747. device.OrganizationCode = newOrgode;
  748. bool success = await _deviceInfoDBServiceProxy.UpdateDeviceInfoByCodeAsync(device.DeviceCode, device, string.Empty, true);
  749. if (success)
  750. {
  751. // 删除已知绑定的用户
  752. var users = await _userServiceProxy.GetUsersByDeviceAsync(device.DeviceCode);
  753. var updateUsers = new List<TableDataItem<UserPasswordDTO>>();
  754. foreach (var user in users)
  755. {
  756. user.BindDevices.Remove(device.DeviceCode);
  757. updateUsers.Add(new TableDataItem<UserPasswordDTO>()
  758. {
  759. Data = user.MappingTo<UserPasswordDTO>(),
  760. });
  761. }
  762. if (updateUsers.Count > 0)
  763. {
  764. var updateUsersDBRequest = new UpdateUsersDBRequest() { Users = updateUsers };
  765. await _userServiceProxy.UpdateUsersAsync(updateUsersDBRequest);
  766. }
  767. if (oldOrg.Isinvented) // 虚拟医院
  768. {
  769. //迁移数据超声机上传检查记录
  770. await _recordsInfoDBService.UpdateRecordsWithOrgCodeAsync(new List<string>() { device.DeviceCode }, newOrgode);
  771. //迁移数据超声机上传病人
  772. await _patientInfoDBService.UpdatePatientWithOrgCodeAsync(new List<string>() { device.DeviceCode }, newOrgode);
  773. }
  774. }
  775. return success;
  776. }
  777. catch (System.Exception ex)
  778. {
  779. Logger.WriteLineError($"AddDeviceToOrgAsync error {ex}");
  780. }
  781. return false;
  782. }
  783. /// <summary>
  784. /// 补齐设备扩展信息
  785. /// </summary>
  786. /// <param name="deviceInfoDOList"></param>
  787. /// <returns></returns>
  788. private async Task<List<DeviceExtendInfoDTO>> MapToExtendDTO(List<DeviceInfoDTO> deviceInfoDOList)
  789. {
  790. var deviceList = new List<DeviceExtendInfoDTO>();
  791. if (deviceInfoDOList != null && deviceInfoDOList.Any())
  792. {
  793. //查询机构
  794. var orgCodes = deviceInfoDOList.Select(x => x.OrganizationCode).ToList();
  795. orgCodes.AddRange(deviceInfoDOList.Select(x => x.DepartmentCode));
  796. var organizations = await _organizationDBService.FindOrganizationListByCodesAsync(orgCodes.Distinct().ToList());
  797. //查询机构负责人
  798. var organizationDirectorCodes = new List<string>();
  799. foreach (var org in organizations)
  800. {
  801. if (org.Directors != null && org.Directors.Any())
  802. {
  803. organizationDirectorCodes.AddRange(org.Directors);
  804. }
  805. }
  806. var organizationDirectors = await _userServiceProxy.FindUserListByUserCodesAsync(organizationDirectorCodes);
  807. var deviceCodes = deviceInfoDOList.Select(x => x.DeviceCode).ToList();
  808. var deviceTokens = await _authenticationService.GetTokenWithClientIdsAsync(new GetTokenWithClientIdsRequest { ClientIds = deviceCodes });
  809. var deviceTypeList = await _deviceInfoDBServiceProxy.FindDictionaryItemsAsync(new FindDictionaryItemsDBRequest { DictionaryType = (int)DictionaryTypeEnum.DeviceType });
  810. foreach (var dto in deviceInfoDOList)
  811. {
  812. var device = dto.MappingTo<DeviceExtendInfoDTO>();
  813. device.IsOnline = deviceTokens.FirstOrDefault(x => x.ClientId == dto.DeviceCode)?.IsOnline ?? false;
  814. device.DepartmentName = organizations.FirstOrDefault(x => x.OrganizationCode == dto.DepartmentCode)?.OrganizationName;
  815. device.LanguageConfigs = deviceTypeList.FirstOrDefault(t => t.DictionaryCode == device.DeviceType)?.LanguageConfigs;
  816. var organization = organizations.FirstOrDefault(x => x.OrganizationCode == dto.OrganizationCode);
  817. if (organization != null)
  818. {
  819. device.OrganizationName = organization.OrganizationName;
  820. if (organization.Directors != null && organization.Directors.Any())
  821. {
  822. var director = organizationDirectors.FirstOrDefault(x => x.UserCode == organization.Directors.FirstOrDefault());
  823. device.OrganizationDirectorCode = director?.UserCode;
  824. device.OrganizationDirectorUserName = director?.UserName;
  825. device.OrganizationDirectorFullName = director?.FullName;
  826. }
  827. }
  828. deviceList.Add(device);
  829. }
  830. }
  831. return deviceList;
  832. }
  833. /// <summary>
  834. /// 补齐设备扩展信息
  835. /// </summary>
  836. /// <param name="deviceInfoDOList"></param>
  837. /// <returns></returns>
  838. private async Task<DeviceExtendInfoDTO> MapToExtendDTO(DeviceInfoDTO deviceInfoDO)
  839. {
  840. var deviceList = await MapToExtendDTO(new List<DeviceInfoDTO> { deviceInfoDO });
  841. return deviceList.FirstOrDefault();
  842. }
  843. /// <summary>
  844. /// 获取设备绑定用户codes
  845. /// </summary>
  846. /// <param name="request">获取设备绑定用户codes请求实体</param>
  847. /// <returns>test01,test02</returns>
  848. public async Task<List<string>> GetDeviceBindUsersCodesAsync(GetDeviceRequest request)
  849. {
  850. //检查设备编码不为空
  851. if (string.IsNullOrWhiteSpace(request.DeviceCode))
  852. {
  853. ThrowCustomerException(CustomerRpcCode.DeviceCodeIsEmpty, "Required parameter:DeviceCode cannot be empty");
  854. }
  855. //查询设备对象
  856. var deviceDb = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(request.DeviceCode);
  857. if (deviceDb == null)
  858. {
  859. ThrowCustomerException(CustomerRpcCode.NoExistDevice, "Device does not exist");
  860. }
  861. var userListResult = await _userServiceProxy.GetUsersByDeviceAsync(request.DeviceCode);
  862. if (userListResult != null && userListResult.Count > 0)
  863. {
  864. return userListResult.Select(u => u.UserCode).ToList();
  865. }
  866. return new List<string>();
  867. }
  868. /// <summary>
  869. /// 查询设备AI应用的状态
  870. /// </summary>
  871. /// <param name="request">请求参数</param>
  872. /// <returns>AI应用集合</returns>
  873. public async Task<List<DiagnosisModuleDTO>> FindDeviceDiagnosisModulesAsync(FindDeviceDiagnosisModulesRequest request)
  874. {
  875. //检查设备编码不为空
  876. if (string.IsNullOrWhiteSpace(request.DeviceCode))
  877. {
  878. ThrowCustomerException(CustomerRpcCode.DeviceCodeIsEmpty, "Required parameter:DeviceCode cannot be empty");
  879. }
  880. return await _diagnosisModuleService.GetDeviceDiagnosisModulesAsync(new GetDeviceDiagnosisModulesDBRequest { DeviceCode = request.DeviceCode });
  881. }
  882. /// <summary>
  883. /// 修改设备AI应用启用状态
  884. /// </summary>
  885. /// <param name="request">修改设备AI应用启用状态请求实体</param>
  886. /// <returns>是否成功</returns>
  887. /// <para>DeviceErrorCodeEnum</para>
  888. public async Task<bool> ModifyDeviceDiagnosisModuleStateAsync(ModifyDeviceDiagnosisModuleStateRequest request)
  889. {
  890. //检查设备编码不为空
  891. if (string.IsNullOrWhiteSpace(request.DeviceCode))
  892. {
  893. ThrowCustomerException(CustomerRpcCode.DeviceCodeIsEmpty, "Required parameter:DeviceCode cannot be empty");
  894. }
  895. if (string.IsNullOrWhiteSpace(request.DiagnosisModule))
  896. {
  897. ThrowCustomerException(CustomerRpcCode.DeviceAIDiagnosisModule, "Required parameter:DeviceCode cannot be empty");
  898. }
  899. var result = await _diagnosisModuleService.UpdateDeviceDiagnosisModuleStateAsync(new UpdateDeviceDiagnosisModuleStateDBRequest
  900. {
  901. DeviceCode = request.DeviceCode,
  902. DiagnosisModule = request.DiagnosisModule,
  903. Enabled = request.Enabled
  904. });
  905. CacheMaintenance.Instance.Get<IDeviceInfosManager>().Remove(request.DeviceCode);
  906. return result;
  907. }
  908. /// <summary>
  909. /// 设备离开会诊房间
  910. /// </summary>
  911. /// <param name="request">设备离开会诊房间请求实体</param>
  912. /// <returns></returns>
  913. public async Task<DeviceLeaveLiveConsultationResult> DeviceLeaveLiveConsultationAsync(DeviceLeaveLiveConsultationRequest request)
  914. {
  915. var deviceCode = await GetClientIdByTokenAsync(request.Token);
  916. var result = new DeviceLeaveLiveConsultationResult
  917. {
  918. Success = false,
  919. };
  920. return result;
  921. }
  922. /// <summary>
  923. /// 通用异常处理方法
  924. /// </summary>
  925. /// <param name="customerRpcCodeEnum">异常标识码</param>
  926. /// <param name="msg">异常信息</param>
  927. /// <param name="internalMessage">内部异常信息,非必填</param>
  928. private void ThrowCustomerException(CustomerRpcCode customerRpcCodeEnum, string msg, string internalMessage = null)
  929. {
  930. ThrowRpcException((int)customerRpcCodeEnum, msg, internalMessage);
  931. }
  932. /// <summary>
  933. /// 上报设备画面尺寸相关信息
  934. /// </summary>
  935. /// <param name="request"></param>
  936. /// <docFirstDirectory>设备端API</docFirstDirectory>
  937. /// <docSecondDirectory>实时会诊服务接口</docSecondDirectory>
  938. /// <docThirdDirectory>会诊</docThirdDirectory>
  939. /// <returns></returns>
  940. public async Task<ReportVideoDeviceInfoResult> ReportVideoDeviceInfoAsync(ReportVideoDeviceInfoRequest request)
  941. {
  942. var result = new ReportVideoDeviceInfoResult();
  943. if (request.VideoDeviceInfos == null || request.VideoDeviceInfos.Count == 0)
  944. {
  945. //视屏设备画面信息为空
  946. ThrowCustomerException(CustomerRpcCode.VideoDeviceInfosEmpty, "VideoDeviceInfosEmpty");
  947. }
  948. if (request.VideoDeviceInfos.Any(x => string.IsNullOrWhiteSpace(x.VideoDeviceId)))
  949. {
  950. //视屏设备ID为空
  951. ThrowCustomerException(CustomerRpcCode.VideoDeviceIdEmpty, "VideoDeviceIdEmpty");
  952. }
  953. var videoDeviceIdCount = request.VideoDeviceInfos.Select(x => x.VideoDeviceId).Distinct().Count();
  954. if (videoDeviceIdCount < request.VideoDeviceInfos.Count)
  955. {
  956. //视屏设备ID重复
  957. ThrowCustomerException(CustomerRpcCode.VideoDeviceIdRepeatError, "VideoDeviceIdRepeatError");
  958. }
  959. var deviceCode = await GetClientIdByTokenAsync(request.Token);
  960. var deviceDTO = await _deviceInfoDBServiceProxy.FindDeviceInfoByCodeAsync(deviceCode);
  961. var videoDeviceInfos = new List<VideoDeviceDTO>();
  962. foreach (var video in request.VideoDeviceInfos)
  963. {
  964. var videoDeviceInfo = new VideoDeviceDTO
  965. {
  966. VideoDeviceId = video.VideoDeviceId,
  967. VideoDeviceSourceType = video.VideoDeviceSourceType,
  968. Width = video.Width,
  969. Height = video.Height,
  970. OutputWidth = video.Width,
  971. OutputHeight = video.Height
  972. };
  973. if (deviceDTO.VideoDeviceInfos != null && deviceDTO.VideoDeviceInfos.Any(x => x.VideoDeviceId == video.VideoDeviceId))
  974. {
  975. var oldVideo = deviceDTO.VideoDeviceInfos.FirstOrDefault(x => x.VideoDeviceId == video.VideoDeviceId);
  976. videoDeviceInfo.OutputWidth = oldVideo.OutputWidth;
  977. videoDeviceInfo.OutputHeight = oldVideo.OutputHeight;
  978. videoDeviceInfo.VideoFps = oldVideo.VideoFps;
  979. videoDeviceInfo.VideoBitrate = oldVideo.VideoBitrate;
  980. videoDeviceInfo.MinVideoBitrate = oldVideo.MinVideoBitrate;
  981. }
  982. videoDeviceInfos.Add(videoDeviceInfo);
  983. }
  984. deviceDTO.VideoDeviceInfos = videoDeviceInfos;
  985. var updateVideoDeviceInfosDBRequest = new UpdateVideoDeviceInfosDBRequest
  986. {
  987. DeviceCode = deviceDTO.DeviceCode,
  988. LiveOpened = request.LiveOpened,
  989. VideoDeviceInfos = videoDeviceInfos
  990. };
  991. await _deviceInfoDBServiceProxy.UpdateVideoDeviceInfosAsync(updateVideoDeviceInfosDBRequest);
  992. CacheMaintenance.Instance.Get<IDeviceInfosManager>().Remove(deviceDTO.DeviceCode);
  993. result.Success = true;
  994. return result;
  995. }
  996. /// <summary>
  997. /// 查找有效设备总数量
  998. /// </summary>
  999. /// <returns></returns>
  1000. public async Task<long> GetActiveDeviceCount()
  1001. {
  1002. return await _deviceInfoDBServiceProxy.GetActiveDeviceCount();
  1003. }
  1004. /// <summary>
  1005. /// 设备发送调参初始化数据
  1006. /// </summary>
  1007. /// <param name="request">调参数据请求</param>
  1008. /// <returns></returns>
  1009. public async Task<bool> SendControlParameterByDeviceAsync(SendControlParameterByDeviceRequest request)
  1010. {
  1011. var deviceCode = await GetClientIdByTokenAsync(request.Token);
  1012. var userCode = request.ControlUserCode;
  1013. //发送控制人通知
  1014. if (string.IsNullOrWhiteSpace(userCode))
  1015. {
  1016. ThrowCustomerException(CustomerRpcCode.UsercodeIsEmpty, "User code is empty");
  1017. }
  1018. var userDTO = await _userServiceProxy.FindUserByCodeAsync(userCode);
  1019. if (userDTO == null)
  1020. {
  1021. ThrowCustomerException(CustomerRpcCode.UserNotExistError, "User does not exist");
  1022. }
  1023. var notify = new DeviceParametersNotification()
  1024. {
  1025. DeviceCode = deviceCode,
  1026. ProbeApplication = request.ProbeApplication,
  1027. Parameter = request.Parameter,
  1028. IsResponse = true
  1029. };
  1030. var notificationRequest = new SendNotificationRequest()
  1031. {
  1032. ClientId = userCode,
  1033. Message = notify,
  1034. JsonMessage = Newtonsoft.Json.JsonConvert.SerializeObject(notify),
  1035. NotificationType = notify.NotificationType,
  1036. TransactionType = TransactionTypeEnum.ControlParameter,
  1037. RelevanceCode = userCode,
  1038. ReceiverType = ApplicantTypeEnum.Client
  1039. };
  1040. await _notificationService.PostMessageAsync(notificationRequest);
  1041. return true;
  1042. }
  1043. /// <summary>
  1044. /// 用户进入设备直播房间
  1045. /// </summary>
  1046. /// <param name="request">用户进入设备直播房间请求实体</param>
  1047. /// <returns></returns>
  1048. public async Task<JoinDeviceLiveRoomResult> JoinDeviceLiveRoomAsync(JoinDeviceLiveRoomRequest request)
  1049. {
  1050. var userInfo = await _authenticationService.GetTokenAsync(request);
  1051. var deviceCode = request.DeviceCode;
  1052. var liveRooms = await _rtcService.GetLiveRoomsByDeviceCodeAsync(new GetLiveRoomsByDeviceCodeRequest
  1053. {
  1054. DeviceCode = deviceCode
  1055. });
  1056. var liveRoom = liveRooms?.FirstOrDefault(x => x.Status == LiveRoomStatus.Initiating);
  1057. LiveMemberDTO deviceMemberInfo;
  1058. if (liveRoom != null)
  1059. {
  1060. //设备正在推流
  1061. deviceMemberInfo = liveRoom.Members.FirstOrDefault(x => x.Id == deviceCode);
  1062. if (deviceMemberInfo?.Status == LiveMemberStatusEnum.Joined)
  1063. {
  1064. return new JoinDeviceLiveRoomResult
  1065. {
  1066. RoomNo = liveRoom.RoomNo,
  1067. RtmpUrl = deviceMemberInfo.LiveData.RtmpPullUrl,
  1068. };
  1069. }
  1070. }
  1071. //新增或更新设备直播间 TODO
  1072. var rtcRoomResult = await _rtcService.GetRoomIdAsync(new GetRoomIdRequest
  1073. {
  1074. UniqueId = deviceCode,
  1075. });
  1076. var rtcRoomId = (int)rtcRoomResult.RoomId;
  1077. var initiateResult = await _rtcService.InitiateLiveAsync(new InitiateLiveRequest
  1078. {
  1079. RoomId = deviceCode,
  1080. InitiatorCode = deviceCode,
  1081. IntegerRoomId = rtcRoomId
  1082. });
  1083. //添加观众
  1084. var addOrUpdateViewerResult = await _rtcService.SaveViewerAsync(new SaveViewerRequest
  1085. {
  1086. LiveRoomCode = initiateResult.RoomId,
  1087. UserCode = userInfo.ClientId,
  1088. UserName = userInfo.AccountName,
  1089. });
  1090. //通知设备推流
  1091. deviceMemberInfo = initiateResult.Members.FirstOrDefault(x => x.Id == deviceCode);
  1092. var message = new StartLiveToDeviceNotification
  1093. {
  1094. LiveRoomCode = initiateResult.RoomId,
  1095. RoomNo = initiateResult.RoomNo,
  1096. AppId = _sdkAppId,
  1097. MergedChannel = deviceMemberInfo.MergedChannel,
  1098. MergedVideoOutputWidth = deviceMemberInfo.MergedVideoOutputWidth,
  1099. MergedVideoOutputHeight = deviceMemberInfo.MergedVideoOutputHeight,
  1100. VideoDeviceOutputList = deviceMemberInfo.VideoDeviceInfos.ToList(),
  1101. };
  1102. await BroadcastNotificationAsync(liveRoom.RoomId, new List<string> { deviceCode }, message);
  1103. return new JoinDeviceLiveRoomResult
  1104. {
  1105. RoomNo = initiateResult.RoomNo,
  1106. RtmpUrl = deviceMemberInfo.LiveData.RtmpPullUrl,
  1107. ReportStateIntervalSeconds = _reportStateIntervalSeconds,
  1108. };
  1109. }
  1110. /// <summary>
  1111. /// 用户离开设备直播房间
  1112. /// </summary>
  1113. /// <param name="request">用户离开设备直播房间请求实体</param>
  1114. /// <returns></returns>
  1115. public async Task<bool> LeaveDeviceLiveRoomAsync(LeaveDeviceLiveRoomRequest request)
  1116. {
  1117. var userInfo = await _authenticationService.GetTokenAsync(request);
  1118. var userCode = userInfo.ClientId;
  1119. var rtcRoomId = request.RoomNo;
  1120. var liveRooms = await _rtcService.GetLiveRoomsByRtcRoomIdAsync(new GetLiveRoomsByRtcRoomIdRequest
  1121. {
  1122. RtcRoomId = rtcRoomId
  1123. });
  1124. var liveRoom = liveRooms?.FirstOrDefault(x => x.Status == LiveRoomStatus.Initiating);
  1125. if (liveRoom != null)
  1126. {
  1127. var deviceCode = liveRoom.DeviceInfos?.FirstOrDefault()?.Id;
  1128. //移除观众
  1129. var removeViewerResult = await _rtcService.RemoveViewerAsync(new RemoveViewerRequest
  1130. {
  1131. LiveRoomCode = liveRoom.RoomId,
  1132. UserCode = userInfo.ClientId,
  1133. });
  1134. var expireTime = DateTime.UtcNow.AddSeconds(_reportStateTimeout * -1);
  1135. if (!liveRoom.ViewerInfos.Any(x => x.UserCode != userCode && x.LastReportTime >= expireTime) && !string.IsNullOrWhiteSpace(deviceCode))
  1136. {
  1137. //关闭直播 to device
  1138. var message = new CloseLiveToDeviceNotification
  1139. {
  1140. LiveRoomCode = liveRoom.RoomId,
  1141. };
  1142. await BroadcastNotificationAsync(liveRoom.RoomId, new List<string> { deviceCode }, message);
  1143. }
  1144. }
  1145. return true;
  1146. }
  1147. /// <summary>
  1148. /// 上报观看直播状态
  1149. /// </summary>
  1150. /// <param name="request">上报观看直播状态请求实体</param>
  1151. /// <returns></returns>
  1152. public async Task<bool> ReportLiveViewStateAsync(ReportLiveViewStateRequest request)
  1153. {
  1154. var userInfo = await _authenticationService.GetTokenAsync(request);
  1155. var rtcRoomId = request.RoomNo;
  1156. var liveRooms = await _rtcService.GetLiveRoomsByRtcRoomIdAsync(new GetLiveRoomsByRtcRoomIdRequest
  1157. {
  1158. RtcRoomId = rtcRoomId
  1159. });
  1160. var liveRoom = liveRooms?.FirstOrDefault(x => x.Status == LiveRoomStatus.Initiating);
  1161. if (liveRoom != null)
  1162. {
  1163. //添加观众
  1164. var addOrUpdateViewerResult = await _rtcService.SaveViewerAsync(new SaveViewerRequest
  1165. {
  1166. LiveRoomCode = liveRoom.RoomId,
  1167. UserCode = userInfo.ClientId,
  1168. UserName = userInfo.AccountName,
  1169. });
  1170. }
  1171. return true;
  1172. }
  1173. /// <summary>
  1174. /// 上报直播状态
  1175. /// </summary>
  1176. /// <param name="request">上报直播状态请求实体</param>
  1177. /// <returns></returns>
  1178. public async Task<bool> ReportLiveStateAsync(ReportLiveStateRequest request)
  1179. {
  1180. var tokenInfo = await _authenticationService.GetTokenAsync(request);
  1181. var deviceCode = tokenInfo.ClientId;
  1182. switch (request.LiveState)
  1183. {
  1184. case DeviceLiveStateEnum.Error:
  1185. case DeviceLiveStateEnum.Warning:
  1186. Logger.WriteLineWarn($"DeviceService ReportLiveStateAsync, [{tokenInfo.AccountType.ToString()}]{tokenInfo.AccountName}, state:{request.LiveState.ToString()}, message:{request.Message}");
  1187. break;
  1188. default:
  1189. Logger.WriteLineInfo($"DeviceService ReportLiveStateAsync, [{tokenInfo.AccountType.ToString()}]{tokenInfo.AccountName}, state:{request.LiveState.ToString()}, message:{request.Message}");
  1190. break;
  1191. }
  1192. if (request.LiveState == DeviceLiveStateEnum.Pushing || request.LiveState == DeviceLiveStateEnum.Closed)
  1193. {
  1194. var rtcRoomId = request.RoomNo;
  1195. var liveRooms = await _rtcService.GetLiveRoomsByRtcRoomIdAsync(new GetLiveRoomsByRtcRoomIdRequest
  1196. {
  1197. RtcRoomId = rtcRoomId
  1198. });
  1199. var liveRoom = liveRooms?.FirstOrDefault(x => x.Status == LiveRoomStatus.Initiating);
  1200. if (liveRoom != null)
  1201. {
  1202. var expireTime = DateTime.UtcNow.AddSeconds(_reportStateTimeout * -1);
  1203. var validViewers = liveRoom.ViewerInfos.Where(x => x.LastReportTime >= expireTime)?.ToList() ?? new List<LiveViewerDTO>();
  1204. if (request.LiveState == DeviceLiveStateEnum.Closed && validViewers.Any())
  1205. {
  1206. //关闭直播 to users
  1207. var message = new DeviceLiveFinishedNotification
  1208. {
  1209. LiveRoomCode = liveRoom.RoomId,
  1210. };
  1211. await BroadcastNotificationAsync(liveRoom.RoomId, validViewers.Select(x => x.UserCode).ToList(), message);
  1212. }
  1213. if (request.LiveState == DeviceLiveStateEnum.Pushing && !validViewers.Any())
  1214. {
  1215. //关闭直播 to device
  1216. var message = new CloseLiveToDeviceNotification
  1217. {
  1218. LiveRoomCode = liveRoom.RoomId,
  1219. };
  1220. await BroadcastNotificationAsync(liveRoom.RoomId, new List<string> { deviceCode }, message);
  1221. }
  1222. }
  1223. }
  1224. return await Task.FromResult(true);
  1225. }
  1226. /// <summary>
  1227. /// 获取实时音视频参数
  1228. /// </summary>
  1229. /// <param name="request">获取实时音视频参数请求实体</param>
  1230. /// <returns></returns>
  1231. public async Task<CreateLiveRoomInfoResult> CreateLiveRoomInfoAsync(CreateLiveRoomInfoRequest request)
  1232. {
  1233. Logger.WriteLineInfo($"DeviceService CreateLiveRoomInfoAsync, DeviceUniqueCode:{request.DeviceUniqueCode}, DeviceType:{request.DeviceType}, DeviceModel:{request.DeviceModel}, SoftwareVersion:{request.SoftwareVersion}");
  1234. var userCode = Guid.NewGuid().ToString("N");
  1235. var getUserSignRequest = new GetUserSignRequest
  1236. {
  1237. UserId = userCode,
  1238. };
  1239. var getUserSignResult = await _rtcService.GetUserSignAsync(getUserSignRequest);
  1240. var userSign = getUserSignResult.UserSign;
  1241. var getRoomIdRequest = new GetRoomIdRequest
  1242. {
  1243. UniqueId = userCode,
  1244. };
  1245. var getRoomIdResult = await _rtcService.GetRoomIdAsync(getRoomIdRequest);
  1246. var intRoomNo = (int)getRoomIdResult.RoomId;
  1247. Logger.WriteLineInfo($"DeviceService CreateLiveRoomInfoAsync, DeviceUniqueCode:{request.DeviceUniqueCode}, UserCode:{userCode}, roomNo:{intRoomNo}");
  1248. return new CreateLiveRoomInfoResult
  1249. {
  1250. IsTrtc = !_isRTCSelf,
  1251. UserCode = userCode,
  1252. UserSign = userSign,
  1253. AppId = _sdkAppId,
  1254. RoomNo = intRoomNo,
  1255. };
  1256. }
  1257. private async Task<bool> BroadcastNotificationAsync(string roomId, IList<string> clientIds, NotificationDTO message)
  1258. {
  1259. var broadcastNotificationRequest = new BroadcastRoomNotificationRequest
  1260. {
  1261. RoomId = roomId,
  1262. ClientIds = clientIds,
  1263. Message = message,
  1264. TransactionType = TransactionTypeEnum.Live,
  1265. RelevanceCode = roomId,
  1266. ReceiverType = ApplicantTypeEnum.Client,
  1267. WSConnectType = WSConnectTypeEnum.Default
  1268. };
  1269. return await _rtcService.BroadcastRoomNotificationAsync(broadcastNotificationRequest);
  1270. }
  1271. }
  1272. }