电子药箱通讯服务端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 7 месеца
преди 6 месеца
преди 7 месеца
преди 6 месеца
преди 7 месеца
преди 6 месеца
преди 6 месеца
преди 7 месеца
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. using Microsoft.AspNetCore.Components;
  2. using Microsoft.EntityFrameworkCore;
  3. using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Prism.Commands;
  6. using Prism.Mvvm;
  7. using Prism.Regions;
  8. using PropertyChanged;
  9. using Rdh.ElectronicMedicineKit.EntityFrameworkCore;
  10. using Rdh.ElectronicMedicineKit.Models;
  11. using Rdh.SocketServer.Client.BLL;
  12. using Rdh.SocketServer.Client.Models;
  13. using Rdh.SocketServer.Client.MQ;
  14. using RDH.Data;
  15. using RDH.Data.BLL;
  16. using RDH.Data.Models;
  17. using Serilog;
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Collections.ObjectModel;
  21. using System.Diagnostics;
  22. using System.Linq;
  23. using System.Text;
  24. using System.Threading;
  25. using System.Threading.Tasks;
  26. using System.Transactions;
  27. using System.Windows;
  28. using System.Windows.Input;
  29. using TouchSocket.Core.ByteManager;
  30. using TouchSocket.Sockets;
  31. namespace Rdh.SocketServer.Client.ViewModels
  32. {
  33. [AddINotifyPropertyChangedInterface]
  34. public class MainWindowViewModel : BindableBase
  35. {
  36. private readonly IRegionManager _regionManager;
  37. private readonly ApplicationDbContext _dbContext;
  38. private readonly ITcpService _tcpService;
  39. private readonly Encoding _encoding;
  40. private List<PortableStorageType> _listStorageTypes;
  41. public const String ViewOfData = "有效数据",
  42. ViewOfInvalid = "无效数据",
  43. ViewOfClient = "客户端",
  44. ViewOfLog = "日志";
  45. #region Constructor
  46. public MainWindowViewModel(IRegionManager regionManager, IServiceProvider serviceProvider, ApplicationDbContext dbContext)
  47. {
  48. ListLogs = new ObservableCollection<LogModel>();
  49. _regionManager = regionManager;
  50. _dbContext = dbContext;
  51. var servers = serviceProvider.GetServices<ITcpService>();
  52. _tcpService = servers?.FirstOrDefault(x => x.ServerName == "ElectronicMedicineKit");
  53. _encoding = Encoding.GetEncoding("gb2312");
  54. if (_tcpService != null)
  55. {
  56. if (_tcpService is TcpService service)
  57. {
  58. service.Connecting += (client, e) =>
  59. {
  60. Log($"{client.ID}正在建立连接");
  61. };//有客户端正在连接
  62. service.Connected += (client, e) =>
  63. {
  64. Log($"已从{client.ID}建立连接");
  65. Application.Current.Dispatcher.Invoke(() =>
  66. {
  67. ListClients.Add(new TimeFlagModel<SocketClient>(client));
  68. });
  69. };//有客户端连接
  70. service.Disconnected += (client, e) =>
  71. {
  72. Log($"已从{client.ID}断开连接");
  73. Application.Current.Dispatcher.Invoke(() =>
  74. {
  75. lock (ListClients)
  76. {
  77. for (Int32 i = 0; i < ListClients.Count; i++)
  78. {
  79. if (ListClients[i].Model.IP == client.IP)
  80. {
  81. ListClients.RemoveAt(i);
  82. i--;
  83. }
  84. }
  85. }
  86. });
  87. };//有客户端断开连接
  88. service.Received += Reveiced;
  89. }
  90. Task.Factory.StartNew(() => DataHandle());
  91. }
  92. _dbContext.Database.EnsureCreated();
  93. DeleteDataCommand = new DelegateCommand(DeleteDataCommandHandler);
  94. ClearCommand = new DelegateCommand<String>(ClearCommandHandler);
  95. }
  96. #endregion
  97. #region Properties
  98. public ObservableCollection<Pocket> Pockets { get; set; } = new ObservableCollection<Pocket>();
  99. public Pocket SelectedData { get; set; }
  100. public ObservableCollection<Pocket> InvalidPockets { get; set; } = new ObservableCollection<Pocket>();
  101. public ObservableCollection<LogModel> ListLogs { get; set; }
  102. public ObservableCollection<TimeFlagModel<SocketClient>> ListClients { get; set; } = new ObservableCollection<TimeFlagModel<SocketClient>>();
  103. public ICommand ClearCommand { get; set; }
  104. public ICommand DeleteDataCommand { get; set; }
  105. public string Title { get; set; }
  106. #endregion
  107. public void Init()
  108. {
  109. Task.Run(() =>
  110. {
  111. try
  112. {
  113. using (ConnectionSessionScope conn = new ConnectionSessionScope())
  114. {
  115. PortableStorageTypeBLL portableStorageTypeBLL = new PortableStorageTypeBLL();
  116. _listStorageTypes = portableStorageTypeBLL.ListModels(100, 0);
  117. }
  118. }
  119. catch (Exception ex)
  120. {
  121. Log($"加载药箱类型出错:{ex.Message}", -1);
  122. Serilog.Log.Warning($"{ex.StackTrace}");
  123. }
  124. });
  125. }
  126. #region Private Methods
  127. #region 页面命令处理
  128. //删除数据按钮
  129. private void DeleteDataCommandHandler()
  130. {
  131. if (SelectedData == null)
  132. {
  133. return;
  134. }
  135. RemovePocket(SelectedData);
  136. Log($"删除数据:{SelectedData.Data}");
  137. }
  138. //清空按钮
  139. private void ClearCommandHandler(String view)
  140. {
  141. switch (view)
  142. {
  143. case ViewOfLog:
  144. this.ListLogs.Clear();
  145. break;
  146. case ViewOfInvalid:
  147. InvalidPockets.Clear();
  148. break;
  149. }
  150. }
  151. #endregion
  152. private void Reveiced(SocketClient client, ByteBlock byteBlock, IRequestInfo requestInfo)
  153. {
  154. Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  155. {
  156. Log($"Received from:{client.IP}");
  157. EleMedKitData? data = requestInfo as EleMedKitData;
  158. if (data == null)
  159. {
  160. InvalidPockets.Add(new Pocket(client, null));
  161. }
  162. else
  163. {
  164. if (data.Message == null)
  165. {
  166. Pockets.Add(new Pocket(client, data));
  167. }
  168. else
  169. {
  170. Log($"解析失败:{data.Message}", -1);
  171. InvalidPockets.Add(new Pocket(client, data));
  172. }
  173. }
  174. }));
  175. }
  176. private void DataHandle()
  177. {
  178. while (true)
  179. {
  180. Pocket? curPocket = PeekData();
  181. if (curPocket != null)
  182. {
  183. EleMedKitProtocol responseData = null;
  184. switch (curPocket.Data.ProtocolDataInfo.Command)
  185. {
  186. case EleMedKitCommand.RequestClock:
  187. ClockResponseProtocol clockResponseProtocol = new ClockResponseProtocol();
  188. responseData = clockResponseProtocol;
  189. break;
  190. case EleMedKitCommand.RequestSupplyList:
  191. try
  192. {
  193. ResponseSupplyDrugProtocol responseSupplyDrugProtocol = new ResponseSupplyDrugProtocol();
  194. responseSupplyDrugProtocol.ListSupplyResult = new List<DrugLotProtocol>();
  195. RequestSupplyDrugProtocol requestSupplyDrugProtocol = (RequestSupplyDrugProtocol)curPocket.Data.ProtocolDataInfo;
  196. responseSupplyDrugProtocol.UserInfo = requestSupplyDrugProtocol.UserInfo;
  197. responseSupplyDrugProtocol.EleMedKitCode = requestSupplyDrugProtocol.EleMedKitCode;
  198. String? state = null;
  199. StorageSpacePortableLink? requestStorageLink = null;
  200. using (ConnectionSessionScope conn = new ConnectionSessionScope())
  201. {
  202. requestStorageLink = GetRequestStorageLink(null, requestSupplyDrugProtocol.EleMedKitCode, out state);
  203. }
  204. if (state != null
  205. || requestStorageLink == null)
  206. {
  207. Log("检查药箱信息不通过", -1);
  208. break;
  209. }
  210. responseSupplyDrugProtocol.MedKitTypeCode = GetPortableTypeCode(requestStorageLink);
  211. if (requestSupplyDrugProtocol.ListBarcode != null
  212. && requestSupplyDrugProtocol.ListBarcode.Count > 0)
  213. {
  214. IEnumerable<ItemBarcodeLibrary> barcodeLibraries = new ShouShuShiBLL()
  215. .ListBarcodeInfo(requestSupplyDrugProtocol.ListBarcode.ToArray());
  216. if (barcodeLibraries != null && barcodeLibraries.Count() > 0)
  217. {
  218. IEnumerable<IGrouping<Guid?, ItemBarcodeLibrary>> itemGroups = barcodeLibraries.GroupBy(x => x.ItemKey);
  219. using (TransactionScope transaction = new TransactionScope())
  220. {
  221. using (ConnectionSessionScope conn = new ConnectionSessionScope())
  222. {
  223. UserInfo? requestUser = GetRequestUserInfo(new UserInfoBLL(), requestSupplyDrugProtocol.UserInfo, out state);
  224. if (state != null || requestUser == null)
  225. {
  226. Log("检查用户信息不通过:" + state, -1);
  227. break;
  228. }
  229. foreach (IGrouping<Guid?, ItemBarcodeLibrary> barcodeLibrary in itemGroups)
  230. {
  231. PortableStorageItemBLL portableStorageItemBLL = new PortableStorageItemBLL();
  232. PortableStorageItem? requestPortableStorageItem = GetRequestPortableItem(portableStorageItemBLL,
  233. requestStorageLink, barcodeLibrary.Key.GetValueOrDefault());
  234. if (requestPortableStorageItem == null)
  235. {
  236. //在药箱的配药列表未找到指定药品时,将返回的条码信息标记为“多”
  237. responseSupplyDrugProtocol.ListSupplyResult.AddRange(barcodeLibrary.Select(x => new DrugLotProtocol
  238. {
  239. Barcode = x.Barcode,
  240. SupplyState = SupplyStateCodes.Add,
  241. }));
  242. continue;
  243. }
  244. #region 更新药品库存及记录
  245. //增加药品操作记录
  246. ItemTransactionBLL itemTransactionBLL = new ItemTransactionBLL();
  247. ItemTransaction itemTransaction = new ItemTransaction
  248. {
  249. Key = Guid.NewGuid(),
  250. CreateTime = DateTime.Now,
  251. //DeviceKey = requestStorageLink.StorageSpace.DeviceKey,
  252. ItemKey = barcodeLibrary.Key,
  253. CreateBy = requestUser.Key,
  254. TransactionType = TransactionTypeCodes.MedKitSupplyPlan.ToString(),
  255. Quantity = barcodeLibrary.Count(),
  256. Ext02 = requestStorageLink.PortableStorage?.Code,
  257. };
  258. //增加库存更新记录
  259. StorageSpaceItemTransactionBLL storageSpaceItemTransactionBLL = new StorageSpaceItemTransactionBLL();
  260. StorageSpaceItemTransaction ssiTransaction = new StorageSpaceItemTransaction
  261. {
  262. Key = Guid.NewGuid(),
  263. CreateBy = requestUser.Key,
  264. CreateTime = DateTime.Now,
  265. StorageSpaceItemKey = requestPortableStorageItem.Key,
  266. ItemTransactionKey = itemTransaction.Key,
  267. };
  268. #endregion
  269. PortableStorageItemLotBLL portableStorageItemLotBLL = new PortableStorageItemLotBLL();
  270. SPILItemTransactionBLL sPILItemTransactionBLL = new SPILItemTransactionBLL();
  271. #region 更新批号库存和记录
  272. Int32 totalIncrease = 0;
  273. foreach (ItemBarcodeLibrary b in barcodeLibrary)
  274. {
  275. PortableStorageItemLot portableStorageItemLot = portableStorageItemLotBLL.GetByItemBarcode(b.Barcode);
  276. if (portableStorageItemLot == null)
  277. {
  278. portableStorageItemLot = new PortableStorageItemLot
  279. {
  280. Key = Guid.NewGuid(),
  281. CreateTime = DateTime.Now,
  282. PortableStorageItemkey = requestPortableStorageItem.Key,
  283. Quantity = 1,
  284. ItemKey = requestPortableStorageItem.ItemKey,
  285. LotKey = b.ItemLotKey,
  286. Ext01 = b.Barcode,
  287. };
  288. totalIncrease += 1;
  289. portableStorageItemLotBLL.Save(portableStorageItemLot);
  290. SPILItemTransaction spilTransaction = new SPILItemTransaction
  291. {
  292. Key = Guid.NewGuid(),
  293. CreateTime = DateTime.Now,
  294. Quantity = 1,
  295. ItemLotKey = b.ItemLotKey,
  296. ItemTransactionKey = itemTransaction.Key,
  297. StorageSpaceItemLotKey = portableStorageItemLot.Key,
  298. Ext01 = b.Barcode,
  299. };
  300. sPILItemTransactionBLL.Save(spilTransaction);
  301. }
  302. //生成返回数据
  303. responseSupplyDrugProtocol.ListSupplyResult.Add(new DrugLotProtocol
  304. {
  305. Barcode = b.Barcode,
  306. SupplyState = SupplyStateCodes.Success,
  307. DrugKey = barcodeLibrary.Key.GetValueOrDefault().ToString(),
  308. DrugLotCode = b.ItemLotInfo.LotNo,
  309. });
  310. }
  311. #endregion
  312. if (totalIncrease > 0)
  313. {
  314. itemTransactionBLL.Save(itemTransaction);
  315. //增加药箱药品库存
  316. requestPortableStorageItem.CurrentQuantity = requestPortableStorageItem.CurrentQuantity.GetValueOrDefault() + barcodeLibrary.Count();
  317. portableStorageItemBLL.Update(requestPortableStorageItem);
  318. storageSpaceItemTransactionBLL.Save(ssiTransaction);
  319. }
  320. }
  321. transaction.Complete();
  322. }
  323. }
  324. }
  325. }
  326. responseData = responseSupplyDrugProtocol;
  327. }
  328. catch (Exception ex)
  329. {
  330. Log("查询药品条码信息出错:" + ex.Message, -1);
  331. }
  332. break;
  333. case EleMedKitCommand.RequestLocation:
  334. try
  335. {
  336. LocationResponseProtocol locationResponse = new LocationResponseProtocol();
  337. LocationRequestProtocol locationRequest = (LocationRequestProtocol)curPocket.Data.ProtocolDataInfo;
  338. #region 获取基站绑定的手术间
  339. IEnumerable<RDH.Data.Models.OperationRoom> rooms = new ShouShuShiBLL().ListOperationRoomByStation(locationRequest.StationCode);
  340. if (rooms != null && rooms.Count() > 0)
  341. {
  342. //以3位字符显示手术间号(左侧补0)
  343. locationResponse.SectionCode = rooms.First().RoomId.PadLeft(3, '0');
  344. locationResponse.EleMedKitCode = locationRequest.EleMedKitCode;
  345. responseData = locationResponse;
  346. #region 记录定位
  347. //记录时,使用纯编号(没有左侧的补0)
  348. String simpleMedkitCode = locationRequest.EleMedKitCode.TrimStart('0');
  349. String simpleStationCode = locationRequest.StationCode.TrimStart('0');
  350. PortableStorageTrackBLL portableStorageTrackBLL = new PortableStorageTrackBLL();
  351. PortableStorageTrack lastTrack = portableStorageTrackBLL.GetLastTrackByItem(simpleMedkitCode);
  352. if (lastTrack == null
  353. || lastTrack.CreateTime.GetValueOrDefault().Date < DateTime.Now.Date
  354. || lastTrack.TrackCode != simpleStationCode)
  355. {
  356. using (ConnectionSessionScope scope = new ConnectionSessionScope())
  357. {
  358. PortableStorageTrack curTrack = new PortableStorageTrack();
  359. curTrack.CreateTime = DateTime.Now;
  360. curTrack.ItemCode = simpleMedkitCode;
  361. curTrack.TrackCode = simpleStationCode;
  362. portableStorageTrackBLL.Save(curTrack);
  363. }
  364. }
  365. #endregion
  366. }
  367. else
  368. {
  369. Log($"基站编号[{locationRequest.StationCode}]未配置手术间");
  370. }
  371. #endregion
  372. }
  373. catch (Exception ex)
  374. {
  375. Log("处理定位信息出错:" + ex.Message, -1);
  376. }
  377. break;
  378. case EleMedKitCommand.RequestPatientOperation:
  379. try
  380. {
  381. RequestPatientOperationProtocol requestProtocol = (RequestPatientOperationProtocol)curPocket.Data.ProtocolDataInfo;
  382. if (requestProtocol.RoomCode == null)
  383. {
  384. Log("请求手术信息时,手术间编号为空", -1);
  385. }
  386. else
  387. {
  388. ResponsePatientOperationProtocol responseProtocol = new ResponsePatientOperationProtocol();
  389. responseProtocol.EleMedKitCode = requestProtocol.EleMedKitCode;
  390. responseProtocol.ListOperations = new List<PatientOperationProtocol>();
  391. IEnumerable<RDH.Data.Models.PatientOperationInfo> operationInfos = new ShouShuShiBLL()
  392. .ListOperattionInfoByRoom(requestProtocol.RoomCode.TrimStart('0'));
  393. if (operationInfos != null)
  394. {
  395. responseProtocol.ListOperations.AddRange(operationInfos.Select(x => new PatientOperationProtocol
  396. {
  397. Key = x.Key.GetValueOrDefault().ToString(),
  398. OperationName = SubString(x.OperationName, 10),
  399. PatientCode = x.PatientInfo.PatientId,
  400. Age = GetAge(x.PatientInfo.Birthday),
  401. Gender = GetGender(x.PatientInfo.Gender),
  402. OperationPart = "-",
  403. PatientName = x.PatientInfo.Name,
  404. }));
  405. }
  406. responseData = responseProtocol;
  407. }
  408. }
  409. catch (Exception ex)
  410. {
  411. Log("查询手术排班信息出错:" + ex.Message, -1);
  412. }
  413. break;
  414. case EleMedKitCommand.RequestPatientOperationUsage:
  415. try
  416. {
  417. ResponseOperationUsageProtocol responseUsageData = new ResponseOperationUsageProtocol();
  418. RequestOperationUsageProtocol requestUsageProtocol = (RequestOperationUsageProtocol)curPocket.Data.ProtocolDataInfo;
  419. using (TransactionScope transaction = new TransactionScope())
  420. {
  421. using (ConnectionSessionScope conn = new ConnectionSessionScope())
  422. {
  423. #region 数据验证
  424. responseUsageData.EleMedKitCode = requestUsageProtocol.EleMedKitCode;
  425. //检查药品列表
  426. if (requestUsageProtocol.ListDrugs == null
  427. || requestUsageProtocol.ListDrugs.Count == 0)
  428. {
  429. Log("用药信息为空", -1);
  430. break;
  431. }
  432. //检查用户信息
  433. String state;
  434. UserInfoBLL userInfoBLL = new UserInfoBLL();
  435. UserInfo? requestUser = GetRequestUserInfo(userInfoBLL, requestUsageProtocol.UserInfo, out state);
  436. if (state != null)
  437. {
  438. Log("检查用户信息不通过:" + state, -1);
  439. break;
  440. }
  441. //检查手术排班信息
  442. if (requestUsageProtocol.OperationInfo == null)
  443. {
  444. Log("手术排班信息为空", -1);
  445. break;
  446. }
  447. Guid operationKey;
  448. if (!Guid.TryParse(requestUsageProtocol.OperationInfo.Key, out operationKey))
  449. {
  450. Log("手术排班ID无效:" + requestUsageProtocol.OperationInfo.Key, -1);
  451. break;
  452. }
  453. PatientOperationInfoBLL patientOperationInfoBLL = new PatientOperationInfoBLL();
  454. PatientOperationInfo requestOperation = patientOperationInfoBLL.Get(new PatientOperationInfo
  455. {
  456. Key = operationKey
  457. });
  458. if (requestOperation == null)
  459. {
  460. Log("未找到请求的手术排班:" + requestUsageProtocol.OperationInfo.Key, -1);
  461. break;
  462. }
  463. #endregion
  464. OperationTakeItemBagBLL operationTakeItemBagBLL = new OperationTakeItemBagBLL();
  465. OperationTakeItemBag curTakeBag = operationTakeItemBagBLL.GetByOperation(requestOperation);
  466. #region 保存OperationTakeItemBag
  467. if (curTakeBag == null)
  468. {
  469. curTakeBag = new OperationTakeItemBag();
  470. curTakeBag.CreateTime = DateTime.Now;
  471. curTakeBag.CreateBy = requestUser.Key;
  472. curTakeBag.Key = Guid.NewGuid();
  473. curTakeBag.OperationKey = requestOperation.Key;
  474. curTakeBag.SnapshotKey = Guid.NewGuid();
  475. curTakeBag.Ext02 = requestUsageProtocol.RoomCode;
  476. curTakeBag.Ext05 = requestUsageProtocol.EleMedKitCode;
  477. operationTakeItemBagBLL.Save(curTakeBag);
  478. }
  479. //else
  480. //{
  481. // Log("重复接收到用药信息:" + requestOperation.OperationId, -1);
  482. // break;
  483. //}
  484. #endregion
  485. PortableStorageItemBLL portableStorageItemBLL = new PortableStorageItemBLL();
  486. PortableStorageItemLotBLL portableStorageItemLotBLL = new PortableStorageItemLotBLL();
  487. StorageSpaceItemTransactionBLL storageSpaceItemTransactionBLL = new StorageSpaceItemTransactionBLL();
  488. SPILItemTransactionBLL sPILItemTransactionBLL = new SPILItemTransactionBLL();
  489. OperationTakeItemBLL operationTakeItemBLL = new OperationTakeItemBLL();
  490. IEnumerable<OperationTakeItem> takeHistory = operationTakeItemBLL.ListTakeItemsByTakeBag(curTakeBag);
  491. Boolean drugHandleFlag = true;
  492. #region 根据请求的标签获取对应库存
  493. List<PortableStorageItemLot> usageWithInventory = new List<PortableStorageItemLot>();
  494. foreach (DrugUsageProtocol d in requestUsageProtocol.ListDrugs)
  495. {
  496. OperationTakeItem? historyItem = takeHistory == null
  497. ? null
  498. : takeHistory.FirstOrDefault(x => x.ItemKey.GetValueOrDefault().ToString() == d.DrugKey);
  499. if (historyItem != null)
  500. {
  501. Log($"重复接收到药品用药信息,药品:{historyItem.Item.ItemCommonName}");
  502. }
  503. else
  504. {
  505. if (d.UsageCode == DrugUsageCodes.Used
  506. || d.UsageCode == DrugUsageCodes.Lost
  507. || d.UsageCode == DrugUsageCodes.LastUsed)
  508. {
  509. PortableStorageItemLot inventoryLot = portableStorageItemLotBLL.GetByItemBarcode(d.Barcode);
  510. //if (inventoryLot == null)
  511. //{
  512. // Log("未找到药品条码标签:" + d.Barcode, -1);
  513. // drugHandleFlag = false;
  514. // break;
  515. //}
  516. //if (inventoryLot.PortableStorageItem.Item.Key.ToString() != d.DrugKey)
  517. //{
  518. // Log("上传的药品ID与数据库不符:" + d.DrugKey, -1);
  519. // drugHandleFlag = false;
  520. // break;
  521. //}
  522. if (inventoryLot != null)
  523. {
  524. usageWithInventory.Add(inventoryLot);
  525. }
  526. }
  527. }
  528. }
  529. if (!drugHandleFlag)
  530. {
  531. break;
  532. }
  533. #endregion
  534. #region 更新库存和业务记录
  535. IEnumerable<IGrouping<Guid, PortableStorageItemLot>> inventoryLogGroup = usageWithInventory
  536. .GroupBy(x => x.LotKey.GetValueOrDefault());
  537. //保存OperationTakeItem
  538. foreach (IGrouping<Guid, PortableStorageItemLot> g in inventoryLogGroup)
  539. {
  540. OperationTakeItem operationTakeItem = new OperationTakeItem
  541. {
  542. Key = Guid.NewGuid(),
  543. SnapshotKey = Guid.NewGuid(),
  544. ItemKey = g.First().ItemKey,
  545. Ext01 = g.First().LotKey.GetValueOrDefault().ToString(),
  546. TakeBagKey = curTakeBag.Key,
  547. TakeQuantity = g.Count(),
  548. };
  549. operationTakeItemBLL.Save(operationTakeItem);
  550. //更新PortableStorageItem
  551. PortableStorageItem psi = g.First().PortableStorageItem;
  552. psi.CurrentQuantity = psi.CurrentQuantity.GetValueOrDefault() - g.Count();
  553. portableStorageItemBLL.Update(psi);
  554. //保存StorageSpaceItemTransaction
  555. StorageSpaceItemTransaction ssiTransaction = new StorageSpaceItemTransaction()
  556. {
  557. Key = Guid.NewGuid(),
  558. CreateBy = requestUser.Key,
  559. CreateTime = DateTime.Now,
  560. StorageSpaceItemKey = psi.Key,
  561. ItemTransactionKey = curTakeBag.Key,
  562. Ext01 = g.Count().ToString(),
  563. };
  564. storageSpaceItemTransactionBLL.Save(ssiTransaction);
  565. }
  566. //更新批号库存
  567. foreach (PortableStorageItemLot psil in usageWithInventory)
  568. {
  569. SPILItemTransaction sPILItemTransaction = new SPILItemTransaction()
  570. {
  571. Key = Guid.NewGuid(),
  572. StorageSpaceItemLotKey = psil.Key,
  573. Quantity = 1,
  574. ItemTransactionKey = curTakeBag.Key.GetValueOrDefault(),
  575. ItemLotKey = psil.LotKey,
  576. Ext01 = psil.Ext01,
  577. };
  578. sPILItemTransactionBLL.Save(sPILItemTransaction);
  579. portableStorageItemLotBLL.Delete(psil);
  580. }
  581. #endregion
  582. #region 更新手术状态
  583. //完成时间
  584. requestOperation.OperationOverTime = DateTime.Now;
  585. patientOperationInfoBLL.UpdateCurrent(requestOperation);
  586. #endregion
  587. transaction.Complete();
  588. }
  589. }
  590. responseData = responseUsageData;
  591. }
  592. catch (Exception ex)
  593. {
  594. Log(ex.Message, -1);
  595. }
  596. break;
  597. case EleMedKitCommand.RequestReturnMedKit:
  598. try
  599. {
  600. Log("请求归还");
  601. ResponseMedKitReturnProtocol responseReturnProtocol = new ResponseMedKitReturnProtocol();
  602. RequestMedKitReturnProtocol requestReturnProtocol = (RequestMedKitReturnProtocol)curPocket.Data.ProtocolDataInfo;
  603. responseReturnProtocol.EleMedKitCode = requestReturnProtocol.EleMedKitCode;
  604. String? state = null;
  605. StorageSpacePortableLink? requestStorageLink = null;
  606. UserInfo? requestUser = null;
  607. using (ConnectionSessionScope conn = new ConnectionSessionScope())
  608. {
  609. requestStorageLink = GetRequestStorageLink(null, requestReturnProtocol.EleMedKitCode, out state);
  610. if (state != null
  611. || requestStorageLink == null)
  612. {
  613. Log("检查药箱信息不通过", -1);
  614. break;
  615. }
  616. UserInfoBLL userInfoBLL = new UserInfoBLL();
  617. requestUser = GetRequestUserInfo(userInfoBLL, requestReturnProtocol.UserInfo, out state);
  618. if (state != null || requestUser == null)
  619. {
  620. Log("检查用户信息不通过:" + state, -1);
  621. break;
  622. }
  623. }
  624. responseReturnProtocol.State = new StateProtocol()
  625. {
  626. IsSuccess = true
  627. };
  628. responseData = responseReturnProtocol;
  629. state = MQService.Singleton.RequestReturnMedKit(requestUser, requestStorageLink);
  630. if (state != null)
  631. {
  632. Log("向药箱柜发送退药请求失败:" + state, -1);
  633. }
  634. }
  635. catch (Exception ex)
  636. {
  637. Log("归还出错:" + ex.Message, -1);
  638. }
  639. break;
  640. case EleMedKitCommand.RequestDrugLend:
  641. try
  642. {
  643. Log("请求借药");
  644. RequestDrugLendProtocol requestLendProtocol = (RequestDrugLendProtocol)curPocket.Data.ProtocolDataInfo;
  645. StorageSpacePortableLink? requestStorageLink = null;
  646. String? state = null;
  647. using (ConnectionSessionScope conn = new ConnectionSessionScope())
  648. {
  649. requestStorageLink = GetRequestStorageLink(null, requestLendProtocol.EleMedKitCode, out state);
  650. if (state != null
  651. || requestStorageLink == null)
  652. {
  653. Log("检查药箱信息不通过", -1);
  654. break;
  655. }
  656. //根据药箱定位,获取最近的手术间
  657. PortableStorageTrackBLL portableStorageTrackBLL = new PortableStorageTrackBLL();
  658. PortableStorageTrack lastTrack = portableStorageTrackBLL.GetLastTrackByItem(requestLendProtocol.EleMedKitCode.TrimStart('0'));
  659. if (lastTrack == null)
  660. {
  661. Log($"未找到药箱[{requestLendProtocol.EleMedKitCode}]最近的定位信息");
  662. break;
  663. }
  664. OperationRoomBLL operationRoomBLL = new OperationRoomBLL();
  665. RDH.Data.Models.OperationRoom currentRoom = operationRoomBLL.GetOperationRoomBySignalStation(lastTrack.TrackCode.PadLeft(3, '0'));
  666. if (currentRoom == null)
  667. {
  668. Log($"未找到基站[{lastTrack.TrackCode}]配置的手术间");
  669. break;
  670. }
  671. //根据手术间,获取最近的借药信息
  672. SPILItemTransactionBLL sPILItemTransactionBLL = new SPILItemTransactionBLL();
  673. IEnumerable<SPILItemTransaction> transactions = sPILItemTransactionBLL.ListMekKitDrugLendTransactionByRoom(currentRoom.RoomName.TrimStart('0'));
  674. if (transactions == null || transactions.Count() == 0)
  675. {
  676. Log($"未找到手术间[{currentRoom.RoomName}]的借药记录");
  677. break;
  678. }
  679. //生成返回信息
  680. ResponseLendDrugProtocol response = new ResponseLendDrugProtocol();
  681. response.EleMedKitCode = requestLendProtocol.EleMedKitCode;
  682. response.ListLendResult = new List<SimpleDrugLotProtocol>();
  683. foreach (SPILItemTransaction t in transactions)
  684. {
  685. response.ListLendResult.Add(new SimpleDrugLotProtocol
  686. {
  687. DrugKey = t.ItemTransaction.ItemKey.ToString(),
  688. DrugLotCode = t.ItemLotInfo.LotNo,
  689. Barcode = t.Ext06
  690. });
  691. }
  692. responseData = response;
  693. //更新借药成功的状态
  694. ItemTransactionBLL itemTransactionBLL = new ItemTransactionBLL();
  695. ItemTransaction itemTransaction = transactions.First().ItemTransaction;
  696. itemTransaction.Ext10 = "1";
  697. itemTransactionBLL.Update(itemTransaction);
  698. //ResponseLendDrugProtocol response = new ResponseLendDrugProtocol();
  699. //response.EleMedKitCode = requestLendProtocol.EleMedKitCode;
  700. //response.ListLendResult = new List<SimpleDrugLotProtocol>();
  701. //response.ListLendResult.Add(new SimpleDrugLotProtocol()
  702. //{
  703. // Barcode = "E00000000000000000000011",
  704. // DrugKey = "81992454-f7a9-4385-aae5-78a3ce7af412",
  705. // DrugLotCode = "20230807",
  706. //});
  707. //response.ListLendResult.Add(new SimpleDrugLotProtocol()
  708. //{
  709. // Barcode = "E00000000000000000000002",
  710. // DrugKey = "39383086-f0aa-4ed0-bbe8-e1bf7fba719f",
  711. // DrugLotCode = "20230817",
  712. //});
  713. //responseData = response;
  714. }
  715. }
  716. catch (Exception ex)
  717. {
  718. Log("借药出错:" + ex.Message, -1);
  719. }
  720. break;
  721. case EleMedKitCommand.RequestStartPatientOperation:
  722. try
  723. {
  724. Log("开启手术");
  725. RequestStartPatientOperationProtocol requestLendProtocol = (RequestStartPatientOperationProtocol)curPocket.Data.ProtocolDataInfo;
  726. StorageSpacePortableLink? requestStorageLink = null;
  727. String? state = null;
  728. using (ConnectionSessionScope conn = new ConnectionSessionScope())
  729. {
  730. requestStorageLink = GetRequestStorageLink(null, requestLendProtocol.EleMedKitCode, out state);
  731. if (state != null
  732. || requestStorageLink == null)
  733. {
  734. Log("检查药箱信息不通过", -1);
  735. break;
  736. }
  737. #region 检查手术ID
  738. Guid operationKey;
  739. if (!Guid.TryParse(requestLendProtocol.PatientOperationID, out operationKey))
  740. {
  741. Log("手术排班ID无效:" + requestLendProtocol.PatientOperationID, -1);
  742. break;
  743. }
  744. PatientOperationInfoBLL patientOperationInfoBLL = new PatientOperationInfoBLL();
  745. PatientOperationInfo requestOperation = patientOperationInfoBLL.Get(new PatientOperationInfo
  746. {
  747. Key = operationKey
  748. });
  749. if (requestOperation == null)
  750. {
  751. Log("未找到请求的手术排班:" + requestLendProtocol.PatientOperationID, -1);
  752. break;
  753. }
  754. #endregion
  755. requestOperation.ClientTime = DateTime.Now;
  756. patientOperationInfoBLL.Update(requestOperation);
  757. }
  758. }
  759. catch (Exception ex)
  760. {
  761. Log("开启手术出错:" + ex.Message, -1);
  762. }
  763. break;
  764. }
  765. if (responseData != null)
  766. {
  767. Log("服务器反馈:" + responseData.ToString());
  768. Byte[] responseBytes = _encoding.GetBytes(responseData.ToString());
  769. try
  770. {
  771. _tcpService.SendAsync(curPocket.ClientId, responseBytes, 0, responseBytes.Length);
  772. curPocket.IsHandled = true;
  773. DebugHelper.Log("已处理消息");
  774. RemovePocket(curPocket);
  775. }
  776. catch (Exception ex)
  777. {
  778. Log("服务器反馈出错:" + ex.Message, -1);
  779. }
  780. }
  781. else
  782. {
  783. DebugHelper.Log("未处理的消息");
  784. RemovePocket(curPocket);
  785. }
  786. Thread.Sleep(1);
  787. }
  788. else
  789. {
  790. Thread.Sleep(1000);
  791. }
  792. }
  793. }
  794. private Pocket? PeekData()
  795. {
  796. lock (Pockets)
  797. {
  798. return Pockets.FirstOrDefault();
  799. }
  800. }
  801. private void RemovePocket(Pocket pocket)
  802. {
  803. lock (Pockets)
  804. {
  805. Application.Current.Dispatcher.Invoke(() =>
  806. {
  807. try
  808. {
  809. Pockets.Remove(pocket);
  810. DebugHelper.Log("删除消息");
  811. }
  812. catch (Exception ex)
  813. {
  814. DebugHelper.Log("删除消息失败:" + ex.Message);
  815. }
  816. });
  817. }
  818. }
  819. private void Log(String content, Int32 logLevel = 0)
  820. {
  821. if (Thread.CurrentThread.ManagedThreadId != Application.Current.Dispatcher.Thread.ManagedThreadId)
  822. {
  823. Application.Current.Dispatcher.Invoke(() =>
  824. {
  825. Log(content, logLevel);
  826. });
  827. }
  828. else
  829. {
  830. Serilog.Log.Debug(content, logLevel);
  831. this.ListLogs.Add(new LogModel()
  832. {
  833. Content = content,
  834. LogLevel = logLevel
  835. });
  836. if (this.ListLogs.Count > 100)
  837. {
  838. this.ListLogs.RemoveAt(0);
  839. }
  840. }
  841. }
  842. #region 业务处理
  843. private String GetAge(DateTime birth)
  844. {
  845. Int32 year = DateTime.Now.Year - birth.Year,
  846. month = DateTime.Now.Month - birth.Month,
  847. day = DateTime.Now.Day - birth.Day;
  848. if (year > 0)
  849. {
  850. if (month >= 0)
  851. {
  852. if (day >= 0)
  853. {
  854. return year.ToString() + "岁";
  855. }
  856. }
  857. if (year - 1 > 0)
  858. {
  859. return (year - 1).ToString() + "岁";
  860. }
  861. month += 12;
  862. }
  863. if (month > 0)
  864. {
  865. return month.ToString() + "月";
  866. }
  867. return day.ToString() + "天";
  868. }
  869. private String GetGender(Boolean flag)
  870. {
  871. return flag ? "女" : "男";
  872. }
  873. private String SubString(String source, Int32 maxLength)
  874. {
  875. return source == null
  876. ? String.Empty
  877. : source.Length > maxLength
  878. ? source.Substring(0, maxLength) + ".."
  879. : source;
  880. }
  881. //获取指定药箱的类型代码
  882. private String GetPortableTypeCode(StorageSpacePortableLink link)
  883. {
  884. if (_listStorageTypes != null)
  885. {
  886. PortableStorageType? storageType = _listStorageTypes.FirstOrDefault(x => x.TypeName == link.Ext02);
  887. if (storageType != null)
  888. {
  889. return storageType.TypeCode;
  890. }
  891. }
  892. return "X";
  893. }
  894. //根据请求的用户信息,获取用户数据
  895. private UserInfo? GetRequestUserInfo(UserInfoBLL userInfoBLL, UserInfoProtocol? requestUserData, out String? state)
  896. {
  897. if (requestUserData == null)
  898. {
  899. state = "传入的用户信息无效";
  900. return null;
  901. }
  902. //避免药箱bug,当传入的usercode为空时,使用默认的管理员账号
  903. if (String.IsNullOrEmpty(requestUserData.UserCode))
  904. {
  905. requestUserData.UserCode = "admin";
  906. }
  907. UserInfo? rlt = userInfoBLL.GetByUserId(requestUserData.UserCode);
  908. if (rlt == null)
  909. {
  910. state = "未找到用户信息:" + requestUserData.UserCode;
  911. return null;
  912. }
  913. state = null;
  914. return rlt;
  915. }
  916. private StorageSpacePortableLink? GetRequestStorageLink(StorageSpacePortableLinkBLL? storageSpacePortableLinkBLL, String? medKitCode, out String? state)
  917. {
  918. Int32 codeNumber;
  919. if (!Int32.TryParse(medKitCode, out codeNumber))
  920. {
  921. state = "请求的药箱号为空";
  922. return null;
  923. }
  924. if (storageSpacePortableLinkBLL == null)
  925. {
  926. storageSpacePortableLinkBLL = new StorageSpacePortableLinkBLL();
  927. }
  928. StorageSpacePortableLink? rlt = storageSpacePortableLinkBLL.GetByStorageCode(null, codeNumber.ToString());
  929. if (rlt == null)
  930. {
  931. state = "未找到设备信息";
  932. return null;
  933. }
  934. state = null;
  935. return rlt;
  936. }
  937. private PortableStorageItem? GetRequestPortableItem(PortableStorageItemBLL? portableStorageItemBLL, StorageSpacePortableLink storageLink, Guid itemKey)
  938. {
  939. if (portableStorageItemBLL == null)
  940. {
  941. portableStorageItemBLL = new PortableStorageItemBLL();
  942. }
  943. PortableStorageItem? rlt = portableStorageItemBLL.GetByStorageAndItem(storageLink.PortableStorageKey.GetValueOrDefault(), itemKey);
  944. return rlt;
  945. }
  946. #endregion
  947. #endregion
  948. }
  949. }