Przeglądaj źródła

fix: 补充PDF解析缺失指标 - 菌群层级表/致病菌/其它重要菌属/病原菌属

Xiaogang Liao 3 miesięcy temu
rodzic
commit
fd16dd5a2c

+ 162 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/PdfParseService.java

@@ -247,7 +247,14 @@ public class PdfParseService {
         parseGutFloraTables(lines, "核心菌属构成表", "核心菌属", gutFlora);
         // 解析有害菌属构成表
         parseGutFloraTables(lines, "有害菌属构成表", "有害菌", gutFlora);
-
+        // 解析其它重要菌属
+        parseGutFloraTables(lines, "其它重要菌属构成表", "其它重要菌属", gutFlora);
+        // 解析病原菌属
+        parseGutFloraTables(lines, "病原菌属构成表", "病原菌属", gutFlora);
+        // 解析菌群层级表(菌纲/菌目/菌科/菌属/菌种)
+        parseTaxonomyLevels(lines, gutFlora);
+        // 解析主要消化道致病菌
+        parsePathogenicBacteria(lines, indicators);
         // 解析益生菌
         parseProbioticSection(lines, probioticSpecies);
 
@@ -311,6 +318,17 @@ public class PdfParseService {
                 new String[]{"抗生素风险评估", "个体化食物推荐表"},
                 KNOWN_NEUROTRANSMITTER, "神经递质与激素", indicators);
 
+        // 主要消化道致病菌(inline格式)
+        parseInlinePathogenicBacteria(fullText, indicators);
+
+        // 菌群表(核心菌属/有害菌属/其它重要菌属/病原菌属/益生菌/层级表)
+        parseGutFloraTables(lines, "核心菌属构成表", "核心菌属", gutFlora);
+        parseGutFloraTables(lines, "有害菌属构成表", "有害菌", gutFlora);
+        parseGutFloraTables(lines, "其它重要菌属构成表", "其它重要菌属", gutFlora);
+        parseGutFloraTables(lines, "病原菌属构成表", "病原菌属", gutFlora);
+        parseTaxonomyLevels(lines, gutFlora);
+        parseProbioticSection(lines, probioticSpecies);
+
         result.setDiseaseRisks(diseaseRisks);
         result.setGutFlora(gutFlora);
         result.setProbioticSpecies(probioticSpecies);
@@ -981,6 +999,149 @@ public class PdfParseService {
         }
     }
 
+    // ======================== 菌群层级表解析(菌纲/菌目/菌科/菌属/菌种) ========================
+
+    private void parseTaxonomyLevels(List<String> lines, List<ParsedGutFlora> result) {
+        int sectionStart = -1;
+        for (int i = 0; i < lines.size(); i++) {
+            if (lines.get(i).contains("菌群检出详细列表")) {
+                sectionStart = i;
+                break;
+            }
+        }
+        if (sectionStart < 0) return;
+
+        int sectionEnd = lines.size();
+        for (int i = sectionStart + 1; i < lines.size(); i++) {
+            String line = lines.get(i);
+            if (line.contains("个体化食物推荐表") || line.contains("报告总结") || line.contains("健康总分")) {
+                sectionEnd = i;
+                break;
+            }
+        }
+
+        String[][] levels = {{"纲", "菌纲构成"}, {"目", "菌目构成"}, {"科", "菌科构成"}, {"属", "菌属构成"}, {"种", "菌种构成"}};
+
+        for (String[] level : levels) {
+            String levelChar = level[0];
+            String category = level[1];
+
+            int levelStart = -1;
+            for (int i = sectionStart; i < sectionEnd - 2; i++) {
+                if (lines.get(i).equals(levelChar) && lines.get(i + 1).equals("名称") && lines.get(i + 2).contains("丰度")) {
+                    levelStart = i + 3;
+                    break;
+                }
+            }
+            if (levelStart < 0) continue;
+
+            int idx = levelStart;
+            while (idx + 3 < sectionEnd) {
+                String name = lines.get(idx);
+
+                boolean isNextLevel = false;
+                for (String[] l : levels) {
+                    if (name.equals(l[0])) { isNextLevel = true; break; }
+                }
+                if (isNextLevel || name.contains("其它重要菌属") || name.contains("病原菌属")
+                        || name.contains("核心菌属") || name.contains("有害菌属")
+                        || name.contains("菌群检出详细列表")) {
+                    break;
+                }
+
+                if (name.equals("名称") || name.contains("丰度") || name.contains("人群") || name.contains("检出")) {
+                    idx++; continue;
+                }
+
+                String abundance = lines.get(idx + 1);
+                String popLevel = lines.get(idx + 2);
+                String detRate = lines.get(idx + 3);
+
+                if (abundance.contains("%") || isNumeric(abundance.replaceAll("[^0-9.]", ""))) {
+                    ParsedGutFlora flora = new ParsedGutFlora();
+                    flora.setBacteriaName(name);
+                    flora.setBacteriaValue(cleanNumericValue(abundance));
+                    flora.setPopulationLevel(popLevel);
+                    flora.setDetectionRate(detRate);
+                    flora.setCategory(category);
+                    flora.setLevel(levelChar);
+                    result.add(flora);
+                    idx += 4;
+                } else {
+                    idx++;
+                }
+            }
+        }
+    }
+
+    // ======================== 主要消化道致病菌解析 ========================
+
+    private void parsePathogenicBacteria(List<String> lines, List<ParsedIndicator> result) {
+        int startIdx = -1;
+        for (int i = 0; i < lines.size(); i++) {
+            if (lines.get(i).contains("主要消化道致病菌")) {
+                startIdx = i + 1;
+                break;
+            }
+        }
+        if (startIdx < 0) return;
+
+        for (int i = startIdx; i < lines.size() - 2; i += 3) {
+            String name = lines.get(i);
+            String value = lines.get(i + 1);
+            String status = lines.get(i + 2);
+
+            if (name.contains("致病菌") || name.contains("丰度") || name.contains("评估")
+                    || name.contains("肠道屏障") || name.contains("抗生素")) {
+                break;
+            }
+
+            if (value.contains("%") || value.equals("ND") || value.equals("0")) {
+                ParsedIndicator ind = new ParsedIndicator();
+                ind.setCategory("主要消化道致病菌");
+                ind.setIndicatorName(name);
+                ind.setIndicatorValue(value);
+                ind.setStatus(status);
+                result.add(ind);
+            }
+        }
+    }
+
+    private void parseInlinePathogenicBacteria(String fullText, List<ParsedIndicator> result) {
+        int sidx = fullText.indexOf("主要消化道致病菌");
+        if (sidx == -1) return;
+
+        int eidx = fullText.indexOf("肠道屏障", sidx);
+        if (eidx == -1) eidx = fullText.length();
+        String region = fullText.substring(sidx, eidx);
+
+        for (String name : KNOWN_PATHOGENS) {
+            int idx = region.indexOf(name);
+            if (idx == -1) continue;
+
+            String after = region.substring(idx + name.length());
+            java.util.regex.Matcher m = Pattern.compile("(\\d+%)").matcher(after);
+            if (!m.find()) continue;
+
+            String value = m.group(1);
+            int assessmentStart = idx + name.length() + m.group().length();
+            int assessmentEnd = region.length();
+            for (String nextName : KNOWN_PATHOGENS) {
+                if (nextName.equals(name)) continue;
+                int ni = region.indexOf(nextName, assessmentStart);
+                if (ni != -1 && ni < assessmentEnd) assessmentEnd = ni;
+            }
+            String status = region.substring(Math.min(assessmentStart, assessmentEnd), assessmentEnd).trim();
+
+            ParsedIndicator ind = new ParsedIndicator();
+            ind.setCategory("主要消化道致病菌");
+            ind.setIndicatorName(name);
+            ind.setIndicatorValue(value);
+            ind.setStatus(status);
+            result.add(ind);
+        }
+    }
+
     // ======================== 益生菌解析 ========================
 
     private void parseProbioticSection(List<String> lines, List<ParsedGutFlora> result) {