exam.dart 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import 'dart:convert';
  2. import 'package:fis_jsonrpc/rpc.dart';
  3. import 'package:uuid/uuid.dart';
  4. import 'package:vital_local_database/core/interface/queryable.dart';
  5. import 'package:vitalapp/database/db.dart';
  6. import 'package:vitalapp/database/entities/defines.dart';
  7. import 'package:vitalapp/database/entities/exam.dart';
  8. import 'package:vitalapp/database/entities/exam_batch.dart';
  9. import 'package:vitalapp/store/store.dart';
  10. class ExamServiceMock extends VitalExamService {
  11. ExamServiceMock(super.host);
  12. static const tcmKey = "HEITCMC";
  13. String? get userCode => Store.user.userCode;
  14. @override
  15. Future<String> createExamAsync(CreateExamRequest request) async {
  16. final checkBatch =
  17. await _checkBatch(request.batchNumber!, request.patientCode!);
  18. if (!checkBatch) {
  19. return "";
  20. }
  21. if (request.code != null && request.code!.isNotEmpty) {
  22. ExamEntity? entity = await db.repositories.exam
  23. .singleByCodeWithUserCode(request.code!, userCode!);
  24. if (entity == null) {
  25. // 纯在线记录直接不让离线修改
  26. return "";
  27. }
  28. entity.dataJson = request.examData!;
  29. final result = await db.repositories.exam.update(entity);
  30. return result > 0 ? entity.code : "";
  31. }
  32. final entity = ExamEntity();
  33. entity.isValid = true;
  34. entity.syncType = OfflineDataSyncType.create;
  35. // 本地先生成一个Code,上传后更新
  36. final uuid = const Uuid().v4().replaceAll('-', '');
  37. entity.code = "mock_$uuid";
  38. entity.userCode = userCode!;
  39. entity.patientCode = request.patientCode!;
  40. entity.batchNumber = request.batchNumber!;
  41. entity.physicalEaxmNumber = request.physicalExamNumber!;
  42. entity.templateKey = request.key!;
  43. entity.templateCode = request.templateCode ?? "";
  44. entity.dataJson = request.examData!;
  45. final id = await db.repositories.exam.insert(entity);
  46. final success = id > 0;
  47. if (success) {
  48. // 统计数量+1
  49. if (request.key == tcmKey) {
  50. await db.repositories.patient
  51. .increaseTCMConsitutionCount(request.patientCode!, userCode!);
  52. } else {
  53. await db.repositories.patient
  54. .increaseExamCount(request.patientCode!, userCode!);
  55. }
  56. }
  57. return success ? entity.code : "";
  58. }
  59. /// 目前仅中医体质用
  60. @override
  61. Future<bool> updateExamAsync(UpdateExamRequest request) async {
  62. ExamEntity? entity = await db.repositories.exam
  63. .singleByCodeWithUserCode(request.code!, userCode!);
  64. if (entity == null) {
  65. // TODO: 此时拿不到批次号、体检号等信息,无法创建完整的离线数据,先直接返回失败
  66. return false;
  67. }
  68. entity.dataJson = request.examData!;
  69. final rows = await db.repositories.exam.update(entity);
  70. return rows > 0;
  71. }
  72. @override
  73. Future<bool> updateExamByBatchNumberAsync(
  74. UpdateExamByBatchNumberRequest request) async {
  75. final entity = await db.repositories.exam.queryable
  76. .where((x) => [
  77. x.isValid.equals(true),
  78. x.batchNumber.equals(request.batchNumber),
  79. x.patientCode.equals(request.patientCode),
  80. x.templateKey.equals(request.key),
  81. ])
  82. .first();
  83. if (entity == null) {
  84. // TODO: 此时拿不到批次号、体检号等信息,无法创建完整的离线数据,先直接返回失败
  85. return false;
  86. }
  87. entity.dataJson = request.examData!;
  88. final rows = await db.repositories.exam.update(entity);
  89. return rows > 0;
  90. }
  91. @override
  92. Future<List<ExamDTO>> getExamByBatchNumberAsync(
  93. GetExamByBatchNumberRequest request) async {
  94. final entities = await db.repositories.exam.queryable
  95. .where((x) => [
  96. x.isValid.equals(true),
  97. x.userCode.equals(true),
  98. x.isValid.equals(request.batchNumber),
  99. ])
  100. .toList();
  101. if (entities.isEmpty) {
  102. return [];
  103. }
  104. final patientCode = entities.first.patientCode;
  105. final patient = await db.repositories.patient
  106. .singleByCodeWithUserCode(patientCode, userCode!);
  107. List<ExamDTO> dtos = [];
  108. for (var entity in entities) {
  109. final dto = ExamDTO(
  110. code: entity.code,
  111. key: entity.templateKey,
  112. patientCode: entity.patientCode,
  113. patientName: patient?.name ?? "",
  114. examDoctor: Store.user.displayName,
  115. physicalExamNumber: entity.physicalEaxmNumber,
  116. batchNumber: entity.batchNumber,
  117. templateCode: entity.templateCode,
  118. createTime: entity.createTime,
  119. updateTime: entity.updateTime,
  120. examData: entity.dataJson,
  121. );
  122. dtos.add(dto);
  123. }
  124. return dtos;
  125. }
  126. @override
  127. Future<PageCollection<ExamConclusionDTO>> getPatientExamByPageAsync(
  128. GetPatientExamByPageRequest request) async {
  129. var query = db.repositories.exam.queryable.where((x) => [
  130. x.isValid.equals(true),
  131. x.userCode.equals(userCode),
  132. x.patientCode.equals(request.patientCode),
  133. x.templateKey.equals(request.examKey),
  134. ]);
  135. final count = await query.count();
  136. final offset = request.pageSize * (request.pageIndex - 1);
  137. final entities = await query
  138. .orderBy((x) => x.updateTime, DbOrderByType.desc)
  139. .orderBy((x) => x.createTime, DbOrderByType.desc)
  140. .offset(offset)
  141. .limit(request.pageSize)
  142. .toList();
  143. List<ExamConclusionDTO> dtos = [];
  144. if (entities.isNotEmpty) {
  145. final isTCM = request.examKey == "HEITCMC";
  146. final patient = await db.repositories.patient
  147. .singleByCodeWithUserCode(request.patientCode!, userCode!);
  148. for (var entity in entities) {
  149. final dto = ExamConclusionDTO(
  150. code: entity.code,
  151. key: entity.templateKey,
  152. patientCode: entity.patientCode,
  153. patientName: patient?.name ?? "",
  154. examDoctor: Store.user.displayName,
  155. physicalExamNumber: entity.physicalEaxmNumber,
  156. batchNumber: entity.batchNumber,
  157. templateCode: entity.templateCode,
  158. createTime: entity.createTime,
  159. updateTime: entity.updateTime ?? entity.createTime,
  160. examData: entity.dataJson,
  161. );
  162. if (entity.syncState != OfflineDataSyncState.success) {
  163. dto.contractedDoctor = "NOT_UPLOADED"; // TODO: 先借用一下此字段
  164. }
  165. if (isTCM) {
  166. final jsonMap = jsonDecode(entity.dataJson);
  167. dto.tcmConclusion = jsonMap["PhysicalConclusion"];
  168. }
  169. dtos.add(dto);
  170. }
  171. }
  172. final result = PageCollection<ExamConclusionDTO>(
  173. currentPage: request.pageIndex,
  174. pageIndex: request.pageIndex,
  175. pageSize: request.pageSize,
  176. totalCount: count,
  177. dataCount: dtos.length,
  178. pageData: dtos,
  179. );
  180. return result;
  181. }
  182. @override
  183. Future<List<ExamRecordDTO>> getExamRecordListAsync(
  184. GetExamRecordListRequest request) async {
  185. final entities = await db.repositories.exam
  186. .queryPatientAllList(request.patientCode!, userCode!);
  187. if (entities.isEmpty) {
  188. return [];
  189. }
  190. final patient = await db.repositories.patient
  191. .singleByCodeWithUserCode(request.patientCode!, userCode!);
  192. final batchMap = <String, ExamRecordDTO>{};
  193. for (var entity in entities) {
  194. if (!batchMap.containsKey(entity.batchNumber)) {
  195. batchMap[entity.batchNumber] = ExamRecordDTO(
  196. batchNumber: entity.batchNumber,
  197. patientName: patient?.name,
  198. examDoctor: Store.user.displayName,
  199. examRecordDatas: [],
  200. );
  201. }
  202. final dto = batchMap[entity.batchNumber]!;
  203. if (dto.examTime == null || (dto.examTime!.isAfter(entity.createTime))) {
  204. dto.examTime = entity.createTime;
  205. }
  206. dto.examRecordDatas!.add(
  207. ExamRecordDataDTO(
  208. code: entity.code,
  209. key: entity.templateKey,
  210. templateCode: entity.templateCode,
  211. examData: entity.dataJson,
  212. ),
  213. );
  214. }
  215. return batchMap.values.toList();
  216. }
  217. Future<bool> _checkBatch(String batchNumber, String patientCode) async {
  218. final hisCount = await db.repositories.examBatch.queryable
  219. .where((x) => [
  220. x.isValid.equals(true),
  221. x.batchNumber.equals(batchNumber),
  222. x.patientCode.equals(patientCode),
  223. ])
  224. .count();
  225. if (hisCount > 0) {
  226. // 已存在。不重复创建
  227. return true;
  228. }
  229. final entity = ExamBatchEntity();
  230. entity.isValid = true;
  231. entity.batchNumber = batchNumber;
  232. entity.patientCode = patientCode;
  233. entity.userCode = Store.user.userCode!;
  234. final batchId = await db.repositories.examBatch.insert(entity);
  235. return batchId > 0;
  236. }
  237. }