|
|
@@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
-import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
+
|
|
|
+import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
import jakarta.annotation.Resource;
|
|
|
@@ -506,12 +508,12 @@ public class PatientRecordServiceImpl implements PatientRecordService {
|
|
|
|
|
|
@Override
|
|
|
public List<RecordDetailItemDTO> getDetailListById(String id) {
|
|
|
- // 查询数据库返回的记录列表
|
|
|
List<Map<String, Object>> mapList = patientRecordMapper.selectDetailMapById(id);
|
|
|
List<RecordDetailItemDTO> dtoList = new ArrayList<>();
|
|
|
|
|
|
for (Map<String, Object> map : mapList) {
|
|
|
String content = (String) map.get("content");
|
|
|
+ String typeName = (String) map.get("typeName");
|
|
|
|
|
|
// 判断 content 是否为空或为 "[]"
|
|
|
if (content == null || content.isEmpty() || "[]".equals(content)) {
|
|
|
@@ -521,13 +523,16 @@ public class PatientRecordServiceImpl implements PatientRecordService {
|
|
|
// 创建 RecordDetailItemDTO 对象,并填充数据
|
|
|
RecordDetailItemDTO dto = new RecordDetailItemDTO();
|
|
|
dto.setType(map.get("type") != null ? ((Number) map.get("type")).longValue() : null);
|
|
|
- dto.setTypeName((String) map.get("typeName"));
|
|
|
- dto.setContent(content);
|
|
|
+ dto.setTypeName(typeName);
|
|
|
+
|
|
|
+ // 根据 typeName 判断是否需要拆分 content 或格式化
|
|
|
+ String formattedContent = formatContentByType(content, typeName);
|
|
|
+ dto.setContent(formattedContent); // 设置格式化后的内容
|
|
|
|
|
|
// 处理 qcComments
|
|
|
String qcCommentsStr = (String) map.get("qcComments");
|
|
|
List<Map<String, Object>> qcCommentsList = processQcComments(qcCommentsStr);
|
|
|
- dto.setQcCommentsList(qcCommentsList); // 将处理后的结果设置到 dto 中
|
|
|
+ dto.setQcCommentsList(qcCommentsList);
|
|
|
|
|
|
// 处理其他字段
|
|
|
dto.setQcResult(map.get("qcResult") != null ? ((Number) map.get("qcResult")).intValue() : null);
|
|
|
@@ -539,9 +544,147 @@ public class PatientRecordServiceImpl implements PatientRecordService {
|
|
|
dtoList.add(dto);
|
|
|
}
|
|
|
|
|
|
- return dtoList; // 返回处理好的详情列表
|
|
|
+ return dtoList;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String formatContentByType(String content, String typeName) {
|
|
|
+ StringBuilder formattedContent = new StringBuilder();
|
|
|
+
|
|
|
+ switch (typeName) {
|
|
|
+ case "病程记录":
|
|
|
+ case "阶段小结":
|
|
|
+ case "查房记录":
|
|
|
+ case "会诊记录":
|
|
|
+ case "疑难病例讨论记录":
|
|
|
+ case "超长住院讨论记录":
|
|
|
+ case "死亡病例讨论记录":
|
|
|
+ case "抢救记录":
|
|
|
+ case "手术记录":
|
|
|
+ case "医嘱记录":
|
|
|
+ case "知情同意书":
|
|
|
+ // 这些类型是数组,需要逐条拆分
|
|
|
+ formattedContent.append(formatMedicalRecords(content));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case "检验报告单":
|
|
|
+ case "检查报告单":
|
|
|
+ // 检验 / 检查报告单单独格式化
|
|
|
+ formattedContent.append(formatLabReportContent(content));
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ // 其他类型直接返回
|
|
|
+ formattedContent.append(content);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return formattedContent.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通用数组类的处理(病程记录、医嘱等)
|
|
|
+ */
|
|
|
+ private String formatMedicalRecords(String content) {
|
|
|
+ StringBuilder formattedContent = new StringBuilder();
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<String> records = objectMapper.readValue(content, List.class);
|
|
|
+
|
|
|
+ for (String record : records) {
|
|
|
+ if (!record.trim().isEmpty()) {
|
|
|
+ formattedContent.append(record.trim()).append("\n\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return "解析记录失败";
|
|
|
+ }
|
|
|
+
|
|
|
+ return formattedContent.toString().trim();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检验/检查报告单的专用格式化
|
|
|
+ */
|
|
|
+ public String formatLabReportContent(String content) {
|
|
|
+ if (content == null || content.trim().isEmpty()) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ StringBuilder formattedContent = new StringBuilder();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 解析JSON数组,每个元素为一份报告
|
|
|
+ List<String> reports = objectMapper.readValue(content, List.class);
|
|
|
+
|
|
|
+ for (String report : reports) {
|
|
|
+ if (report == null || report.trim().isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ String text = report;
|
|
|
+
|
|
|
+ // 1. 统一长横线分隔
|
|
|
+ text = text.replaceAll("-{5,}", "\n-------------------------------------------------------------------------------------------------\n")
|
|
|
+ .replaceAll("检验结果[-]+", "\n检验结果:\n")
|
|
|
+ .replaceAll("◆", "\n◆");
|
|
|
+
|
|
|
+ // 2. 病人信息整合到一行,确保格式一致
|
|
|
+ text = text.replaceAll("(病人姓名|性别|年龄|科室|门诊号|住院号|床号)([^\\n]+)", "$1:$2");
|
|
|
+
|
|
|
+ // 3. 处理检验项目和检验结果格式
|
|
|
+ text = text.replaceAll("检验项目", "\n检验项目")
|
|
|
+ .replaceAll("检验结果", "检验结果");
|
|
|
+
|
|
|
+ // 4. 保持原始的 "检验项目 检验结果 单位 结果标志 结果参考" 行不变,统一格式
|
|
|
+ text = text.replaceAll("(检验项目|检验结果|单位|结果标志|结果参考)", "$1");
|
|
|
+
|
|
|
+ // 5. 处理特殊简短报告(如乙肝、梅毒等)
|
|
|
+ if (text.contains("检验结果:") && (text.contains("HBsAg") || text.contains("抗-HBs") || text.contains("梅毒螺旋体抗体"))) {
|
|
|
+ text = text.replaceAll("检验结果:", "\n检验结果:\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ text = text.replaceAll("结果参考", "结果参考 ");
|
|
|
+
|
|
|
+ // >>>>>>>> 新增:自动在每个检验项目前换行 <<<<<<<<
|
|
|
+ text = text.replaceAll("(◆?)([\\u4e00-\\u9fa5]+\\([^)]+\\))", "\n$1$2"); // 特别处理包含-的项
|
|
|
+
|
|
|
+ // 修复:◆开头的行,如果下一行以中文开头,且上一行以字母/数字结尾,则合并
|
|
|
+ text = text.replaceAll("(◆[\\S&&[^◆]]*)\n([\\u4e00-\\u9fa5])", "$1$2");
|
|
|
+
|
|
|
+
|
|
|
+ // 6. 统一处理检验项目格式,保持一致
|
|
|
+ text = text.replaceAll("(◆[^\n]+)([\\d\\.]+)", "$1 $2");
|
|
|
+
|
|
|
+ // 7. 去除多余的空格和空行
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ String[] lines = text.split("\n");
|
|
|
+ for (String line : lines) {
|
|
|
+ if (!line.trim().isEmpty()) {
|
|
|
+ sb.append(line.trim()).append("\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 拼接报告,并确保报告之间有空行分隔
|
|
|
+ formattedContent.append(sb.toString().trim())
|
|
|
+ .append("\n\n========================================================== 分隔线 ==========================================================\n\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return "解析检验报告失败";
|
|
|
+ }
|
|
|
+
|
|
|
+ return formattedContent.toString().trim();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
private List<RecordDetailItemDTO> convertToDtoList(List<Map<String, Object>> mapList) {
|
|
|
List<RecordDetailItemDTO> dtoList = new ArrayList<>();
|
|
|
|
|
|
@@ -617,27 +760,65 @@ public class PatientRecordServiceImpl implements PatientRecordService {
|
|
|
private List<Map<String, Object>> processQcComments(String qcCommentsStr) {
|
|
|
List<Map<String, Object>> qcCommentsList = new ArrayList<>();
|
|
|
|
|
|
- // 确保 qcCommentsStr 不为空
|
|
|
- if (qcCommentsStr != null && !qcCommentsStr.isEmpty()) {
|
|
|
- try {
|
|
|
- // 使用 Jackson ObjectMapper 来解析 JSON 字符串
|
|
|
- ObjectMapper objectMapper = new ObjectMapper();
|
|
|
- // 解析字符串为 List<Map<String, Object>> 类型
|
|
|
- List<Map<String, Object>> comments = objectMapper.readValue(qcCommentsStr, List.class);
|
|
|
-
|
|
|
- // 遍历并过滤出 result 为 "fail" 的记录
|
|
|
- for (Map<String, Object> comment : comments) {
|
|
|
- if ("fail".equals(comment.get("result"))) {
|
|
|
- qcCommentsList.add(comment); // 只保留审核失败的记录
|
|
|
- }
|
|
|
+ if (qcCommentsStr == null || qcCommentsStr.trim().isEmpty()) {
|
|
|
+ return qcCommentsList;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 多步骤清理
|
|
|
+ String cleanedJson = qcCommentsStr.trim();
|
|
|
+
|
|
|
+ // 步骤1: 移除Markdown代码块
|
|
|
+ cleanedJson = removeMarkdownWrapper(cleanedJson);
|
|
|
+
|
|
|
+ // 步骤2: 移除其他可能的非法字符
|
|
|
+ cleanedJson = removeIllegalCharacters(cleanedJson);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
|
+
|
|
|
+ List<Map<String, Object>> comments = objectMapper.readValue(cleanedJson,
|
|
|
+ new TypeReference<List<Map<String, Object>>>() {});
|
|
|
+
|
|
|
+ for (Map<String, Object> comment : comments) {
|
|
|
+ if ("fail".equals(comment.get("result"))) {
|
|
|
+ qcCommentsList.add(comment);
|
|
|
}
|
|
|
- } catch (JsonProcessingException e) {
|
|
|
- // 处理 JSON 解析异常
|
|
|
- e.printStackTrace(); // 可以根据需求添加更多的异常处理逻辑
|
|
|
}
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.err.println("处理qc_comments失败: " + e.getMessage());
|
|
|
+ System.err.println("请检查数据库中的qc_comments字段内容,应该是纯JSON格式");
|
|
|
+ e.printStackTrace();
|
|
|
}
|
|
|
|
|
|
- return qcCommentsList; // 返回处理后的审核失败记录列表
|
|
|
+ return qcCommentsList;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String removeMarkdownWrapper(String str) {
|
|
|
+ if (str == null) return null;
|
|
|
+
|
|
|
+ String cleaned = str.trim();
|
|
|
+
|
|
|
+ // 移除各种Markdown代码块格式
|
|
|
+ cleaned = cleaned.replaceAll("^```(json|JSON)?\\s*", "");
|
|
|
+ cleaned = cleaned.replaceAll("\\s*```$", "");
|
|
|
+ cleaned = cleaned.replaceAll("^``(json|JSON)?\\s*", "");
|
|
|
+ cleaned = cleaned.replaceAll("\\s*``$", "");
|
|
|
+
|
|
|
+ return cleaned.trim();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String removeIllegalCharacters(String str) {
|
|
|
+ if (str == null) return null;
|
|
|
+
|
|
|
+ // 移除BOM字符和其他控制字符
|
|
|
+ return str.replace("\uFEFF", "")
|
|
|
+ .replaceAll("^[\\p{C}]+", "")
|
|
|
+ .replaceAll("[\\p{C}]+$", "")
|
|
|
+ .trim();
|
|
|
}
|
|
|
|
|
|
|