DeviceService.cs 62 KB

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