import 'dart:convert'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:uuid/uuid.dart'; import 'package:vital_local_database/core/interface/queryable.dart'; import 'package:vitalapp/database/db.dart'; import 'package:vitalapp/database/entities/defines.dart'; import 'package:vitalapp/database/entities/exam.dart'; import 'package:vitalapp/database/entities/exam_batch.dart'; import 'package:vitalapp/store/store.dart'; class ExamServiceMock extends VitalExamService { ExamServiceMock(super.host); static const tcmKey = "HEITCMC"; String? get userCode => Store.user.userCode; @override Future createExamAsync(CreateExamRequest request) async { final checkBatch = await _checkBatch(request.batchNumber!, request.patientCode!); if (!checkBatch) { return ""; } if (request.code != null && request.code!.isNotEmpty) { ExamEntity? entity = await db.repositories.exam .singleByCodeWithUserCode(request.code!, userCode!); if (entity == null) { // 纯在线记录直接不让离线修改 return ""; } entity.dataJson = request.examData!; final result = await db.repositories.exam.update(entity); return result > 0 ? entity.code : ""; } final entity = ExamEntity(); entity.isValid = true; entity.syncType = OfflineDataSyncType.create; // 本地先生成一个Code,上传后更新 final uuid = const Uuid().v4().replaceAll('-', ''); entity.code = "mock_$uuid"; entity.userCode = userCode!; entity.patientCode = request.patientCode!; entity.batchNumber = request.batchNumber!; entity.physicalEaxmNumber = request.physicalExamNumber!; entity.templateKey = request.key!; entity.templateCode = request.templateCode ?? ""; entity.dataJson = request.examData!; final id = await db.repositories.exam.insert(entity); final success = id > 0; if (success) { // 统计数量+1 if (request.key == tcmKey) { await db.repositories.patient .increaseTCMConsitutionCount(request.patientCode!, userCode!); } else { await db.repositories.patient .increaseExamCount(request.patientCode!, userCode!); } } return success ? entity.code : ""; } /// 目前仅中医体质用 @override Future updateExamAsync(UpdateExamRequest request) async { ExamEntity? entity = await db.repositories.exam .singleByCodeWithUserCode(request.code!, userCode!); if (entity == null) { // TODO: 此时拿不到批次号、体检号等信息,无法创建完整的离线数据,先直接返回失败 return false; } entity.dataJson = request.examData!; final rows = await db.repositories.exam.update(entity); return rows > 0; } @override Future updateExamByBatchNumberAsync( UpdateExamByBatchNumberRequest request) async { final entity = await db.repositories.exam.queryable .where((x) => [ x.isValid.equals(true), x.batchNumber.equals(request.batchNumber), x.patientCode.equals(request.patientCode), x.templateKey.equals(request.key), ]) .first(); if (entity == null) { // TODO: 此时拿不到批次号、体检号等信息,无法创建完整的离线数据,先直接返回失败 return false; } entity.dataJson = request.examData!; final rows = await db.repositories.exam.update(entity); return rows > 0; } @override Future> getExamByBatchNumberAsync( GetExamByBatchNumberRequest request) async { final entities = await db.repositories.exam.queryable .where((x) => [ x.isValid.equals(true), x.userCode.equals(true), x.isValid.equals(request.batchNumber), ]) .toList(); if (entities.isEmpty) { return []; } final patientCode = entities.first.patientCode; final patient = await db.repositories.patient .singleByCodeWithUserCode(patientCode, userCode!); List dtos = []; for (var entity in entities) { final dto = ExamDTO( code: entity.code, key: entity.templateKey, patientCode: entity.patientCode, patientName: patient?.name ?? "", examDoctor: Store.user.displayName, physicalExamNumber: entity.physicalEaxmNumber, batchNumber: entity.batchNumber, templateCode: entity.templateCode, createTime: entity.createTime, updateTime: entity.updateTime, examData: entity.dataJson, ); dtos.add(dto); } return dtos; } @override Future> getPatientExamByPageAsync( GetPatientExamByPageRequest request) async { var query = db.repositories.exam.queryable.where((x) => [ x.isValid.equals(true), x.userCode.equals(userCode), x.patientCode.equals(request.patientCode), x.templateKey.equals(request.examKey), ]); final count = await query.count(); final offset = request.pageSize * (request.pageIndex - 1); final entities = await query .orderBy((x) => x.updateTime, DbOrderByType.desc) .orderBy((x) => x.createTime, DbOrderByType.desc) .offset(offset) .limit(request.pageSize) .toList(); List dtos = []; if (entities.isNotEmpty) { final isTCM = request.examKey == "HEITCMC"; final patient = await db.repositories.patient .singleByCodeWithUserCode(request.patientCode!, userCode!); for (var entity in entities) { final dto = ExamConclusionDTO( code: entity.code, key: entity.templateKey, patientCode: entity.patientCode, patientName: patient?.name ?? "", examDoctor: Store.user.displayName, physicalExamNumber: entity.physicalEaxmNumber, batchNumber: entity.batchNumber, templateCode: entity.templateCode, createTime: entity.createTime, updateTime: entity.updateTime ?? entity.createTime, examData: entity.dataJson, ); if (entity.syncState != OfflineDataSyncState.success) { dto.contractedDoctor = "NOT_UPLOADED"; // TODO: 先借用一下此字段 } if (isTCM) { final jsonMap = jsonDecode(entity.dataJson); dto.tcmConclusion = jsonMap["PhysicalConclusion"]; } dtos.add(dto); } } final result = PageCollection( currentPage: request.pageIndex, pageIndex: request.pageIndex, pageSize: request.pageSize, totalCount: count, dataCount: dtos.length, pageData: dtos, ); return result; } @override Future> getExamRecordListAsync( GetExamRecordListRequest request) async { final entities = await db.repositories.exam .queryPatientAllList(request.patientCode!, userCode!); if (entities.isEmpty) { return []; } final patient = await db.repositories.patient .singleByCodeWithUserCode(request.patientCode!, userCode!); final batchMap = {}; for (var entity in entities) { if (!batchMap.containsKey(entity.batchNumber)) { batchMap[entity.batchNumber] = ExamRecordDTO( batchNumber: entity.batchNumber, patientName: patient?.name, examDoctor: Store.user.displayName, examRecordDatas: [], ); } final dto = batchMap[entity.batchNumber]!; if (dto.examTime == null || (dto.examTime!.isAfter(entity.createTime))) { dto.examTime = entity.createTime; } dto.examRecordDatas!.add( ExamRecordDataDTO( code: entity.code, key: entity.templateKey, templateCode: entity.templateCode, examData: entity.dataJson, ), ); } return batchMap.values.toList(); } Future _checkBatch(String batchNumber, String patientCode) async { final hisCount = await db.repositories.examBatch.queryable .where((x) => [ x.isValid.equals(true), x.batchNumber.equals(batchNumber), x.patientCode.equals(patientCode), ]) .count(); if (hisCount > 0) { // 已存在。不重复创建 return true; } final entity = ExamBatchEntity(); entity.isValid = true; entity.batchNumber = batchNumber; entity.patientCode = patientCode; entity.userCode = Store.user.userCode!; final batchId = await db.repositories.examBatch.insert(entity); return batchId > 0; } }